From f6592a9e2cdd63133763f8b9171e2b6051db2393 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Sun, 1 Feb 2004 17:34:44 +0000 Subject: [PATCH] deque.tcc: Wrap overlong lines... 2004-02-01 Paolo Carlini * include/bits/deque.tcc: Wrap overlong lines, constify a few variables, reformat according to the coding standards. * include/bits/list.tcc: Likewise. * include/bits/stl_deque.h: Likewise. * include/bits/stl_function.h: Likewise. * include/bits/stl_iterator.h: Likewise. * include/bits/stl_iterator_base_funcs.h: Likewise. * include/bits/stl_iterator_base_types.h: Likewise. * include/bits/stl_list.h: Likewise. * include/bits/stl_map.h: Likewise. * include/bits/stl_multimap.h: Likewise. * include/bits/stl_multiset.h: Likewise. * include/bits/stl_relops.h: Likewise. * include/bits/stl_set.h: Likewise. From-SVN: r77077 --- libstdc++-v3/ChangeLog | 17 + libstdc++-v3/include/bits/deque.tcc | 567 ++--- libstdc++-v3/include/bits/list.tcc | 124 +- libstdc++-v3/include/bits/stl_deque.h | 2184 +++++++++-------- libstdc++-v3/include/bits/stl_function.h | 1356 +++++----- libstdc++-v3/include/bits/stl_iterator.h | 188 +- .../include/bits/stl_iterator_base_funcs.h | 26 +- .../include/bits/stl_iterator_base_types.h | 8 +- libstdc++-v3/include/bits/stl_list.h | 82 +- libstdc++-v3/include/bits/stl_map.h | 1003 ++++---- libstdc++-v3/include/bits/stl_multimap.h | 911 +++---- libstdc++-v3/include/bits/stl_multiset.h | 770 +++--- libstdc++-v3/include/bits/stl_relops.h | 106 +- libstdc++-v3/include/bits/stl_set.h | 156 +- 14 files changed, 3963 insertions(+), 3535 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 897134e041d..ed6d807544d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,20 @@ +2004-02-01 Paolo Carlini + + * include/bits/deque.tcc: Wrap overlong lines, constify + a few variables, reformat according to the coding standards. + * include/bits/list.tcc: Likewise. + * include/bits/stl_deque.h: Likewise. + * include/bits/stl_function.h: Likewise. + * include/bits/stl_iterator.h: Likewise. + * include/bits/stl_iterator_base_funcs.h: Likewise. + * include/bits/stl_iterator_base_types.h: Likewise. + * include/bits/stl_list.h: Likewise. + * include/bits/stl_map.h: Likewise. + * include/bits/stl_multimap.h: Likewise. + * include/bits/stl_multiset.h: Likewise. + * include/bits/stl_relops.h: Likewise. + * include/bits/stl_set.h: Likewise. + 2004-02-01 Paolo Carlini * include/bits/stl_bvector.h: Wrap overlong lines, constify diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 9f01eed8d68..2f26edfb3af 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -1,6 +1,6 @@ // Deque implementation (out of line) -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -70,16 +70,17 @@ namespace __gnu_norm { const size_type __len = size(); if (&__x != this) - { - if (__len >= __x.size()) - erase(std::copy(__x.begin(), __x.end(), this->_M_start), this->_M_finish); - else - { - const_iterator __mid = __x.begin() + difference_type(__len); - std::copy(__x.begin(), __mid, this->_M_start); - insert(this->_M_finish, __mid, __x.end()); - } - } + { + if (__len >= __x.size()) + erase(std::copy(__x.begin(), __x.end(), this->_M_start), + this->_M_finish); + else + { + const_iterator __mid = __x.begin() + difference_type(__len); + std::copy(__x.begin(), __mid, this->_M_start); + insert(this->_M_finish, __mid, __x.end()); + } + } return *this; } @@ -89,17 +90,17 @@ namespace __gnu_norm insert(iterator position, const value_type& __x) { if (position._M_cur == this->_M_start._M_cur) - { - push_front(__x); - return this->_M_start; - } + { + push_front(__x); + return this->_M_start; + } else if (position._M_cur == this->_M_finish._M_cur) - { - push_back(__x); - iterator __tmp = this->_M_finish; - --__tmp; - return __tmp; - } + { + push_back(__x); + iterator __tmp = this->_M_finish; + --__tmp; + return __tmp; + } else return _M_insert_aux(position, __x); } @@ -113,15 +114,15 @@ namespace __gnu_norm ++__next; size_type __index = __position - this->_M_start; if (__index < (size() >> 1)) - { - std::copy_backward(this->_M_start, __position, __next); - pop_front(); - } + { + std::copy_backward(this->_M_start, __position, __next); + pop_front(); + } else - { - std::copy(__next, this->_M_finish, __position); - pop_back(); - } + { + std::copy(__next, this->_M_finish, __position); + pop_back(); + } return this->_M_start + __index; } @@ -131,33 +132,33 @@ namespace __gnu_norm erase(iterator __first, iterator __last) { if (__first == this->_M_start && __last == this->_M_finish) - { - clear(); - return this->_M_finish; - } + { + clear(); + return this->_M_finish; + } else - { - difference_type __n = __last - __first; - difference_type __elems_before = __first - this->_M_start; - if (static_cast(__elems_before) < (size() - __n) / 2) - { - std::copy_backward(this->_M_start, __first, __last); - iterator __new_start = this->_M_start + __n; - std::_Destroy(this->_M_start, __new_start); - _M_destroy_nodes(this->_M_start._M_node, __new_start._M_node); - this->_M_start = __new_start; - } - else - { - std::copy(__last, this->_M_finish, __first); - iterator __new_finish = this->_M_finish - __n; - std::_Destroy(__new_finish, this->_M_finish); - _M_destroy_nodes(__new_finish._M_node + 1, - this->_M_finish._M_node + 1); - this->_M_finish = __new_finish; - } - return this->_M_start + __elems_before; - } + { + const difference_type __n = __last - __first; + const difference_type __elems_before = __first - this->_M_start; + if (static_cast(__elems_before) < (size() - __n) / 2) + { + std::copy_backward(this->_M_start, __first, __last); + iterator __new_start = this->_M_start + __n; + std::_Destroy(this->_M_start, __new_start); + _M_destroy_nodes(this->_M_start._M_node, __new_start._M_node); + this->_M_start = __new_start; + } + else + { + std::copy(__last, this->_M_finish, __first); + iterator __new_finish = this->_M_finish - __n; + std::_Destroy(__new_finish, this->_M_finish); + _M_destroy_nodes(__new_finish._M_node + 1, + this->_M_finish._M_node + 1); + this->_M_finish = __new_finish; + } + return this->_M_start + __elems_before; + } } template @@ -168,20 +169,20 @@ namespace __gnu_norm for (_Map_pointer __node = this->_M_start._M_node + 1; __node < this->_M_finish._M_node; ++__node) - { - std::_Destroy(*__node, *__node + _S_buffer_size()); - _M_deallocate_node(*__node); - } + { + std::_Destroy(*__node, *__node + _S_buffer_size()); + _M_deallocate_node(*__node); + } if (this->_M_start._M_node != this->_M_finish._M_node) - { - std::_Destroy(this->_M_start._M_cur, this->_M_start._M_last); - std::_Destroy(this->_M_finish._M_first, this->_M_finish._M_cur); - _M_deallocate_node(this->_M_finish._M_first); - } + { + std::_Destroy(this->_M_start._M_cur, this->_M_start._M_last); + std::_Destroy(this->_M_finish._M_first, this->_M_finish._M_cur); + _M_deallocate_node(this->_M_finish._M_first); + } else std::_Destroy(this->_M_start._M_cur, this->_M_finish._M_cur); - + this->_M_finish = this->_M_start; } @@ -189,7 +190,8 @@ namespace __gnu_norm template void deque<_Tp,_Alloc> - ::_M_assign_aux(_InputIterator __first, _InputIterator __last, input_iterator_tag) + ::_M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag) { iterator __cur = begin(); for ( ; __first != __last && __cur != end(); ++__cur, ++__first) @@ -206,34 +208,34 @@ namespace __gnu_norm _M_fill_insert(iterator __pos, size_type __n, const value_type& __x) { if (__pos._M_cur == this->_M_start._M_cur) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - try - { - std::uninitialized_fill(__new_start, this->_M_start, __x); - this->_M_start = __new_start; - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_fill(__new_start, this->_M_start, __x); + this->_M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + __throw_exception_again; + } + } else if (__pos._M_cur == this->_M_finish._M_cur) - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - try - { - std::uninitialized_fill(this->_M_finish, __new_finish, __x); - this->_M_finish = __new_finish; - } - catch(...) - { - _M_destroy_nodes(this->_M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } - } + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_fill(this->_M_finish, __new_finish, __x); + this->_M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } else _M_insert_aux(__pos, __n, __x); } @@ -288,7 +290,7 @@ namespace __gnu_norm _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, forward_iterator_tag) { - size_type __n = std::distance(__first, __last); + const size_type __n = std::distance(__first, __last); this->_M_initialize_map(__n); _Map_pointer __cur_node; @@ -389,9 +391,7 @@ namespace __gnu_norm _M_range_insert_aux(iterator __pos, _InputIterator __first, _InputIterator __last, input_iterator_tag) - { - std::copy(__first, __last, std::inserter(*this, __pos)); - } + { std::copy(__first, __last, std::inserter(*this, __pos)); } template template @@ -403,34 +403,34 @@ namespace __gnu_norm { size_type __n = std::distance(__first, __last); if (__pos._M_cur == this->_M_start._M_cur) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - try - { - std::uninitialized_copy(__first, __last, __new_start); - this->_M_start = __new_start; - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + try + { + std::uninitialized_copy(__first, __last, __new_start); + this->_M_start = __new_start; + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + __throw_exception_again; + } + } else if (__pos._M_cur == this->_M_finish._M_cur) - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - try - { - std::uninitialized_copy(__first, __last, this->_M_finish); - this->_M_finish = __new_finish; - } - catch(...) - { - _M_destroy_nodes(this->_M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } - } + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + try + { + std::uninitialized_copy(__first, __last, this->_M_finish); + this->_M_finish = __new_finish; + } + catch(...) + { + _M_destroy_nodes(this->_M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } else _M_insert_aux(__pos, __first, __last, __n); } @@ -443,27 +443,27 @@ namespace __gnu_norm difference_type __index = __pos - this->_M_start; value_type __x_copy = __x; // XXX copy if (static_cast(__index) < size() / 2) - { - push_front(front()); - iterator __front1 = this->_M_start; - ++__front1; - iterator __front2 = __front1; - ++__front2; - __pos = this->_M_start + __index; - iterator __pos1 = __pos; - ++__pos1; - std::copy(__front2, __pos1, __front1); - } + { + push_front(front()); + iterator __front1 = this->_M_start; + ++__front1; + iterator __front2 = __front1; + ++__front2; + __pos = this->_M_start + __index; + iterator __pos1 = __pos; + ++__pos1; + std::copy(__front2, __pos1, __front1); + } else - { - push_back(back()); - iterator __back1 = this->_M_finish; - --__back1; - iterator __back2 = __back1; - --__back2; - __pos = this->_M_start + __index; - std::copy_backward(__pos, __back2, __back1); - } + { + push_back(back()); + iterator __back1 = this->_M_finish; + --__back1; + iterator __back2 = __back1; + --__back2; + __pos = this->_M_start + __index; + std::copy_backward(__pos, __back2, __back1); + } *__pos = __x_copy; return __pos; } @@ -477,69 +477,73 @@ namespace __gnu_norm size_type __length = this->size(); value_type __x_copy = __x; if (__elems_before < difference_type(__length / 2)) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = this->_M_start; - __pos = this->_M_start + __elems_before; - try - { - if (__elems_before >= difference_type(__n)) - { - iterator __start_n = this->_M_start + difference_type(__n); - std::uninitialized_copy(this->_M_start, __start_n, __new_start); - this->_M_start = __new_start; - std::copy(__start_n, __pos, __old_start); - fill(__pos - difference_type(__n), __pos, __x_copy); - } - else - { - std::__uninitialized_copy_fill(this->_M_start, __pos, __new_start, - this->_M_start, __x_copy); - this->_M_start = __new_start; - std::fill(__old_start, __pos, __x_copy); - } - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_start; + __pos = this->_M_start + __elems_before; + try + { + if (__elems_before >= difference_type(__n)) + { + iterator __start_n = this->_M_start + difference_type(__n); + std::uninitialized_copy(this->_M_start, __start_n, + __new_start); + this->_M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + fill(__pos - difference_type(__n), __pos, __x_copy); + } + else + { + std::__uninitialized_copy_fill(this->_M_start, __pos, + __new_start, + this->_M_start, __x_copy); + this->_M_start = __new_start; + std::fill(__old_start, __pos, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + __throw_exception_again; + } + } else - { - iterator __new_finish = _M_reserve_elements_at_back(__n); - iterator __old_finish = this->_M_finish; - const difference_type __elems_after = - difference_type(__length) - __elems_before; - __pos = this->_M_finish - __elems_after; - try - { - if (__elems_after > difference_type(__n)) - { - iterator __finish_n = this->_M_finish - difference_type(__n); - std::uninitialized_copy(__finish_n, this->_M_finish, this->_M_finish); - this->_M_finish = __new_finish; - std::copy_backward(__pos, __finish_n, __old_finish); - std::fill(__pos, __pos + difference_type(__n), __x_copy); - } - else - { - std::__uninitialized_fill_copy(this->_M_finish, - __pos + difference_type(__n), - __x_copy, __pos, this->_M_finish); - this->_M_finish = __new_finish; - std::fill(__pos, __old_finish, __x_copy); - } - } - catch(...) - { - _M_destroy_nodes(this->_M_finish._M_node + 1, - __new_finish._M_node + 1); - __throw_exception_again; - } - } + { + iterator __new_finish = _M_reserve_elements_at_back(__n); + iterator __old_finish = this->_M_finish; + const difference_type __elems_after = + difference_type(__length) - __elems_before; + __pos = this->_M_finish - __elems_after; + try + { + if (__elems_after > difference_type(__n)) + { + iterator __finish_n = this->_M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, this->_M_finish, + this->_M_finish); + this->_M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::fill(__pos, __pos + difference_type(__n), __x_copy); + } + else + { + std::__uninitialized_fill_copy(this->_M_finish, + __pos + difference_type(__n), + __x_copy, __pos, + this->_M_finish); + this->_M_finish = __new_finish; + std::fill(__pos, __old_finish, __x_copy); + } + } + catch(...) + { + _M_destroy_nodes(this->_M_finish._M_node + 1, + __new_finish._M_node + 1); + __throw_exception_again; + } + } } - + template template void @@ -551,36 +555,37 @@ namespace __gnu_norm const difference_type __elemsbefore = __pos - this->_M_start; size_type __length = size(); if (static_cast(__elemsbefore) < __length / 2) - { - iterator __new_start = _M_reserve_elements_at_front(__n); - iterator __old_start = this->_M_start; - __pos = this->_M_start + __elemsbefore; - try - { - if (__elemsbefore >= difference_type(__n)) - { - iterator __start_n = this->_M_start + difference_type(__n); - std::uninitialized_copy(this->_M_start, __start_n, __new_start); - this->_M_start = __new_start; - std::copy(__start_n, __pos, __old_start); - std::copy(__first, __last, __pos - difference_type(__n)); - } - else - { - _ForwardIterator __mid = __first; - std::advance(__mid, difference_type(__n) - __elemsbefore); - std::__uninitialized_copy_copy(this->_M_start, __pos, - __first, __mid, __new_start); - this->_M_start = __new_start; - std::copy(__mid, __last, __old_start); - } - } - catch(...) - { - _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); - __throw_exception_again; - } - } + { + iterator __new_start = _M_reserve_elements_at_front(__n); + iterator __old_start = this->_M_start; + __pos = this->_M_start + __elemsbefore; + try + { + if (__elemsbefore >= difference_type(__n)) + { + iterator __start_n = this->_M_start + difference_type(__n); + std::uninitialized_copy(this->_M_start, __start_n, + __new_start); + this->_M_start = __new_start; + std::copy(__start_n, __pos, __old_start); + std::copy(__first, __last, __pos - difference_type(__n)); + } + else + { + _ForwardIterator __mid = __first; + std::advance(__mid, difference_type(__n) - __elemsbefore); + std::__uninitialized_copy_copy(this->_M_start, __pos, + __first, __mid, __new_start); + this->_M_start = __new_start; + std::copy(__mid, __last, __old_start); + } + } + catch(...) + { + _M_destroy_nodes(__new_start._M_node, this->_M_start._M_node); + __throw_exception_again; + } + } else { iterator __new_finish = _M_reserve_elements_at_back(__n); @@ -591,24 +596,25 @@ namespace __gnu_norm try { if (__elemsafter > difference_type(__n)) - { - iterator __finish_n = this->_M_finish - difference_type(__n); - std::uninitialized_copy(__finish_n, - this->_M_finish, - this->_M_finish); - this->_M_finish = __new_finish; - std::copy_backward(__pos, __finish_n, __old_finish); - std::copy(__first, __last, __pos); - } + { + iterator __finish_n = this->_M_finish - difference_type(__n); + std::uninitialized_copy(__finish_n, + this->_M_finish, + this->_M_finish); + this->_M_finish = __new_finish; + std::copy_backward(__pos, __finish_n, __old_finish); + std::copy(__first, __last, __pos); + } else - { - _ForwardIterator __mid = __first; - std::advance(__mid, __elemsafter); - std::__uninitialized_copy_copy(__mid, __last, __pos, - this->_M_finish, this->_M_finish); - this->_M_finish = __new_finish; - std::copy(__first, __mid, __pos); - } + { + _ForwardIterator __mid = __first; + std::advance(__mid, __elemsafter); + std::__uninitialized_copy_copy(__mid, __last, __pos, + this->_M_finish, + this->_M_finish); + this->_M_finish = __new_finish; + std::copy(__first, __mid, __pos); + } } catch(...) { @@ -625,7 +631,7 @@ namespace __gnu_norm _M_new_elements_at_front(size_type __new_elems) { size_type __new_nodes - = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); + = (__new_elems + _S_buffer_size() - 1) / _S_buffer_size(); _M_reserve_map_at_front(__new_nodes); size_type __i; try @@ -674,39 +680,40 @@ namespace __gnu_norm _Map_pointer __new_nstart; if (this->_M_map_size > 2 * __new_num_nodes) - { - __new_nstart - = this->_M_map + (this->_M_map_size - __new_num_nodes) / 2 - + (__add_at_front ? __nodes_to_add : 0); - if (__new_nstart < this->_M_start._M_node) - std::copy(this->_M_start._M_node, + { + __new_nstart = this->_M_map + (this->_M_map_size + - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + if (__new_nstart < this->_M_start._M_node) + std::copy(this->_M_start._M_node, this->_M_finish._M_node + 1, __new_nstart); - else - std::copy_backward(this->_M_start._M_node, - this->_M_finish._M_node + 1, - __new_nstart + __old_num_nodes); - } + else + std::copy_backward(this->_M_start._M_node, + this->_M_finish._M_node + 1, + __new_nstart + __old_num_nodes); + } else - { - size_type __new_map_size = - this->_M_map_size + std::max(this->_M_map_size, __nodes_to_add) + 2; - - _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); - __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 - + (__add_at_front ? __nodes_to_add : 0); - std::copy(this->_M_start._M_node, - this->_M_finish._M_node + 1, - __new_nstart); - _M_deallocate_map(this->_M_map, this->_M_map_size); - - this->_M_map = __new_map; - this->_M_map_size = __new_map_size; - } + { + size_type __new_map_size = this->_M_map_size + + std::max(this->_M_map_size, + __nodes_to_add) + 2; + _Map_pointer __new_map = this->_M_allocate_map(__new_map_size); + __new_nstart = __new_map + (__new_map_size - __new_num_nodes) / 2 + + (__add_at_front ? __nodes_to_add : 0); + std::copy(this->_M_start._M_node, + this->_M_finish._M_node + 1, + __new_nstart); + _M_deallocate_map(this->_M_map, this->_M_map_size); + + this->_M_map = __new_map; + this->_M_map_size = __new_map_size; + } + this->_M_start._M_set_node(__new_nstart); this->_M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } } // namespace __gnu_norm - + #endif diff --git a/libstdc++-v3/include/bits/list.tcc b/libstdc++-v3/include/bits/list.tcc index 2b50518e44e..2c3e670d3b0 100644 --- a/libstdc++-v3/include/bits/list.tcc +++ b/libstdc++-v3/include/bits/list.tcc @@ -1,6 +1,6 @@ // List implementation (out of line) -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -120,18 +120,18 @@ namespace __gnu_norm operator=(const list& __x) { if (this != &__x) - { - iterator __first1 = begin(); - iterator __last1 = end(); - const_iterator __first2 = __x.begin(); - const_iterator __last2 = __x.end(); - while (__first1 != __last1 && __first2 != __last2) - *__first1++ = *__first2++; - if (__first2 == __last2) - erase(__first1, __last1); - else - insert(__last1, __first2, __last2); - } + { + iterator __first1 = begin(); + iterator __last1 = end(); + const_iterator __first2 = __x.begin(); + const_iterator __last2 = __x.end(); + while (__first1 != __last1 && __first2 != __last2) + *__first1++ = *__first2++; + if (__first2 == __last2) + erase(__first1, __last1); + else + insert(__last1, __first2, __last2); + } return *this; } @@ -191,7 +191,8 @@ namespace __gnu_norm { iterator __first = begin(); iterator __last = end(); - if (__first == __last) return; + if (__first == __last) + return; iterator __next = __first; while (++__next != __last) { @@ -245,19 +246,21 @@ namespace __gnu_norm list * __counter; do - { - __carry.splice(__carry.begin(), *this, begin()); - - for(__counter = &__tmp[0]; - (__counter != __fill) && !__counter->empty(); - ++__counter) - { - __counter->merge(__carry); - __carry.swap(*__counter); - } - __carry.swap(*__counter); - if (__counter == __fill) ++__fill; - } while ( !empty() ); + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); for (__counter = &__tmp[1]; __counter != __fill; ++__counter) __counter->merge( *(__counter-1) ); @@ -277,7 +280,8 @@ namespace __gnu_norm { iterator __next = __first; ++__next; - if (__pred(*__first)) _M_erase(__first); + if (__pred(*__first)) + _M_erase(__first); __first = __next; } } @@ -332,39 +336,41 @@ namespace __gnu_norm template template - void - list<_Tp,_Alloc>:: - sort(_StrictWeakOrdering __comp) - { - // Do nothing if the list has length 0 or 1. - if (this->_M_node._M_next != &this->_M_node && - this->_M_node._M_next->_M_next != &this->_M_node) + void + list<_Tp,_Alloc>:: + sort(_StrictWeakOrdering __comp) { - list __carry; - list __tmp[64]; - list * __fill = &__tmp[0]; - list * __counter; - - do - { - __carry.splice(__carry.begin(), *this, begin()); - - for(__counter = &__tmp[0]; - (__counter != __fill) && !__counter->empty(); - ++__counter) - { - __counter->merge(__carry, __comp); - __carry.swap(*__counter); - } - __carry.swap(*__counter); - if (__counter == __fill) ++__fill; - } while ( !empty() ); - - for (__counter = &__tmp[1]; __counter != __fill; ++__counter) - __counter->merge( *(__counter-1), __comp ); - swap( *(__fill-1) ); + // Do nothing if the list has length 0 or 1. + if (this->_M_node._M_next != &this->_M_node + && this->_M_node._M_next->_M_next != &this->_M_node) + { + list __carry; + list __tmp[64]; + list * __fill = &__tmp[0]; + list * __counter; + + do + { + __carry.splice(__carry.begin(), *this, begin()); + + for(__counter = &__tmp[0]; + (__counter != __fill) && !__counter->empty(); + ++__counter) + { + __counter->merge(__carry, __comp); + __carry.swap(*__counter); + } + __carry.swap(*__counter); + if (__counter == __fill) + ++__fill; + } + while ( !empty() ); + + for (__counter = &__tmp[1]; __counter != __fill; ++__counter) + __counter->merge( *(__counter-1), __comp ); + swap( *(__fill-1) ); + } } - } } // namespace __gnu_norm #endif /* _LIST_TCC */ diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 64a24b1c027..20e6179efe5 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -1,6 +1,6 @@ // Deque implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -98,239 +98,244 @@ namespace __gnu_norm */ template struct _Deque_iterator - { - typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; - typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; - static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } + { + typedef _Deque_iterator<_Tp, _Tp&, _Tp*> iterator; + typedef _Deque_iterator<_Tp, const _Tp&, const _Tp*> const_iterator; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } - typedef random_access_iterator_tag iterator_category; - typedef _Tp value_type; - typedef _Ptr pointer; - typedef _Ref reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef _Tp** _Map_pointer; - typedef _Deque_iterator _Self; + typedef random_access_iterator_tag iterator_category; + typedef _Tp value_type; + typedef _Ptr pointer; + typedef _Ref reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef _Tp** _Map_pointer; + typedef _Deque_iterator _Self; - _Tp* _M_cur; - _Tp* _M_first; - _Tp* _M_last; - _Map_pointer _M_node; - - _Deque_iterator(_Tp* __x, _Map_pointer __y) + _Tp* _M_cur; + _Tp* _M_first; + _Tp* _M_last; + _Map_pointer _M_node; + + _Deque_iterator(_Tp* __x, _Map_pointer __y) : _M_cur(__x), _M_first(*__y), _M_last(*__y + _S_buffer_size()), _M_node(__y) {} - _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} - _Deque_iterator(const iterator& __x) + + _Deque_iterator() : _M_cur(0), _M_first(0), _M_last(0), _M_node(0) {} + + _Deque_iterator(const iterator& __x) : _M_cur(__x._M_cur), _M_first(__x._M_first), _M_last(__x._M_last), _M_node(__x._M_node) {} - reference operator*() const { return *_M_cur; } - pointer operator->() const { return _M_cur; } - - _Self& operator++() { - ++_M_cur; - if (_M_cur == _M_last) { - _M_set_node(_M_node + 1); - _M_cur = _M_first; + reference + operator*() const + { return *_M_cur; } + + pointer + operator->() const + { return _M_cur; } + + _Self& + operator++() + { + ++_M_cur; + if (_M_cur == _M_last) + { + _M_set_node(_M_node + 1); + _M_cur = _M_first; + } + return *this; } - return *this; - } - _Self operator++(int) { - _Self __tmp = *this; - ++*this; - return __tmp; - } - - _Self& operator--() { - if (_M_cur == _M_first) { - _M_set_node(_M_node - 1); - _M_cur = _M_last; + + _Self + operator++(int) + { + _Self __tmp = *this; + ++*this; + return __tmp; } - --_M_cur; - return *this; - } - _Self operator--(int) { - _Self __tmp = *this; - --*this; - return __tmp; - } - - _Self& operator+=(difference_type __n) - { - difference_type __offset = __n + (_M_cur - _M_first); - if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) - _M_cur += __n; - else { - difference_type __node_offset = - __offset > 0 ? __offset / difference_type(_S_buffer_size()) - : -difference_type((-__offset - 1) / _S_buffer_size()) - 1; - _M_set_node(_M_node + __node_offset); - _M_cur = _M_first + - (__offset - __node_offset * difference_type(_S_buffer_size())); + + _Self& + operator--() + { + if (_M_cur == _M_first) + { + _M_set_node(_M_node - 1); + _M_cur = _M_last; + } + --_M_cur; + return *this; + } + + _Self + operator--(int) + { + _Self __tmp = *this; + --*this; + return __tmp; + } + + _Self& + operator+=(difference_type __n) + { + const difference_type __offset = __n + (_M_cur - _M_first); + if (__offset >= 0 && __offset < difference_type(_S_buffer_size())) + _M_cur += __n; + else + { + const difference_type __node_offset = + __offset > 0 ? __offset / difference_type(_S_buffer_size()) + : -difference_type((-__offset - 1) + / _S_buffer_size()) - 1; + _M_set_node(_M_node + __node_offset); + _M_cur = _M_first + (__offset - __node_offset + * difference_type(_S_buffer_size())); + } + return *this; } - return *this; - } - _Self operator+(difference_type __n) const - { - _Self __tmp = *this; - return __tmp += __n; - } + _Self + operator+(difference_type __n) const + { + _Self __tmp = *this; + return __tmp += __n; + } - _Self& operator-=(difference_type __n) { return *this += -__n; } + _Self& + operator-=(difference_type __n) + { return *this += -__n; } - _Self operator-(difference_type __n) const { - _Self __tmp = *this; - return __tmp -= __n; - } + _Self + operator-(difference_type __n) const + { + _Self __tmp = *this; + return __tmp -= __n; + } - reference operator[](difference_type __n) const { return *(*this + __n); } + reference + operator[](difference_type __n) const + { return *(*this + __n); } - /** @if maint - * Prepares to traverse new_node. Sets everything except _M_cur, which - * should therefore be set by the caller immediately afterwards, based on - * _M_first and _M_last. - * @endif - */ - void - _M_set_node(_Map_pointer __new_node) - { - _M_node = __new_node; - _M_first = *__new_node; - _M_last = _M_first + difference_type(_S_buffer_size()); - } - }; + /** @if maint + * Prepares to traverse new_node. Sets everything except _M_cur, which + * should therefore be set by the caller immediately afterwards, based on + * _M_first and _M_last. + * @endif + */ + void + _M_set_node(_Map_pointer __new_node) + { + _M_node = __new_node; + _M_first = *__new_node; + _M_last = _M_first + difference_type(_S_buffer_size()); + } + }; // Note: we also provide overloads whose operands are of the same type in // order to avoid ambiguous overload resolution when std::rel_ops operators // are in scope (for additional details, see libstdc++/3628) template - inline bool - operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return __x._M_cur == __y._M_cur; - } + inline bool + operator==(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __x._M_cur == __y._M_cur; } template - inline bool - operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return __x._M_cur == __y._M_cur; - } + typename _RefR, typename _PtrR> + inline bool + operator==(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __x._M_cur == __y._M_cur; } template - inline bool - operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__x == __y); - } + inline bool + operator!=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x == __y); } template - inline bool - operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__x == __y); - } + typename _RefR, typename _PtrR> + inline bool + operator!=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x == __y); } template - inline bool - operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return (__x._M_node == __y._M_node) ? - (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); - } + inline bool + operator<(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } template - inline bool - operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return (__x._M_node == __y._M_node) ? - (__x._M_cur < __y._M_cur) : (__x._M_node < __y._M_node); - } + typename _RefR, typename _PtrR> + inline bool + operator<(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return (__x._M_node == __y._M_node) ? (__x._M_cur < __y._M_cur) + : (__x._M_node < __y._M_node); } template - inline bool - operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return __y < __x; - } + inline bool + operator>(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return __y < __x; } template - inline bool - operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return __y < __x; - } + typename _RefR, typename _PtrR> + inline bool + operator>(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return __y < __x; } template - inline bool - operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__y < __x); - } + inline bool + operator<=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__y < __x); } template - inline bool - operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__y < __x); - } + typename _RefR, typename _PtrR> + inline bool + operator<=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__y < __x); } template - inline bool - operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, - const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) - { - return !(__x < __y); - } + inline bool + operator>=(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x, + const _Deque_iterator<_Tp, _Ref, _Ptr>& __y) + { return !(__x < __y); } template - inline bool - operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return !(__x < __y); - } + typename _RefR, typename _PtrR> + inline bool + operator>=(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { return !(__x < __y); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template - inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type - operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, - const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) - { - return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type - (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) * - (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + - (__y._M_last - __y._M_cur); - } + typename _RefR, typename _PtrR> + inline typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x, + const _Deque_iterator<_Tp, _RefR, _PtrR>& __y) + { + return typename _Deque_iterator<_Tp, _RefL, _PtrL>::difference_type + (_Deque_iterator<_Tp, _RefL, _PtrL>::_S_buffer_size()) + * (__x._M_node - __y._M_node - 1) + (__x._M_cur - __x._M_first) + + (__y._M_last - __y._M_cur); + } template - inline _Deque_iterator<_Tp, _Ref, _Ptr> - operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) - { - return __x + __n; - } + inline _Deque_iterator<_Tp, _Ref, _Ptr> + operator+(ptrdiff_t __n, const _Deque_iterator<_Tp, _Ref, _Ptr>& __x) + { return __x + __n; } /** * @if maint @@ -347,59 +352,58 @@ namespace __gnu_norm template class _Deque_base : public _Alloc - { - public: - typedef _Alloc allocator_type; - allocator_type get_allocator() const + { + public: + typedef _Alloc allocator_type; + + allocator_type + get_allocator() const { return *static_cast(this); } - typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; - typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; - - _Deque_base(const allocator_type& __a, size_t __num_elements) + typedef _Deque_iterator<_Tp,_Tp&,_Tp*> iterator; + typedef _Deque_iterator<_Tp,const _Tp&,const _Tp*> const_iterator; + + _Deque_base(const allocator_type& __a, size_t __num_elements) : _Alloc(__a), _M_start(), _M_finish() { _M_initialize_map(__num_elements); } - _Deque_base(const allocator_type& __a) - : _Alloc(__a), _M_start(), _M_finish() {} - ~_Deque_base(); - protected: - typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; - _Map_alloc_type _M_get_map_allocator() const + _Deque_base(const allocator_type& __a) + : _Alloc(__a), _M_start(), _M_finish() { } + + ~_Deque_base(); + + protected: + typedef typename _Alloc::template rebind<_Tp*>::other _Map_alloc_type; + _Map_alloc_type _M_get_map_allocator() const { return _Map_alloc_type(this->get_allocator()); } - _Tp* - _M_allocate_node() - { - return _Alloc::allocate(__deque_buf_size(sizeof(_Tp))); - } - - void - _M_deallocate_node(_Tp* __p) - { - _Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); - } - - _Tp** - _M_allocate_map(size_t __n) + _Tp* + _M_allocate_node() + { return _Alloc::allocate(__deque_buf_size(sizeof(_Tp))); } + + void + _M_deallocate_node(_Tp* __p) + { _Alloc::deallocate(__p, __deque_buf_size(sizeof(_Tp))); } + + _Tp** + _M_allocate_map(size_t __n) { return _M_get_map_allocator().allocate(__n); } - void - _M_deallocate_map(_Tp** __p, size_t __n) + void + _M_deallocate_map(_Tp** __p, size_t __n) { _M_get_map_allocator().deallocate(__p, __n); } - - protected: - void _M_initialize_map(size_t); - void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); - void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); - enum { _S_initial_map_size = 8 }; - - _Tp** _M_map; - size_t _M_map_size; - iterator _M_start; - iterator _M_finish; - }; - + + protected: + void _M_initialize_map(size_t); + void _M_create_nodes(_Tp** __nstart, _Tp** __nfinish); + void _M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish); + enum { _S_initial_map_size = 8 }; + + _Tp** _M_map; + size_t _M_map_size; + iterator _M_start; + iterator _M_finish; + }; template _Deque_base<_Tp,_Alloc>::~_Deque_base() @@ -422,64 +426,64 @@ namespace __gnu_norm * @endif */ template - void - _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) - { - size_t __num_nodes = - __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; - - this->_M_map_size - = std::max((size_t) _S_initial_map_size, __num_nodes + 2); - this->_M_map = _M_allocate_map(this->_M_map_size); - - // For "small" maps (needing less than _M_map_size nodes), allocation - // starts in the middle elements and grows outwards. So nstart may be the - // beginning of _M_map, but for small maps it may be as far in as _M_map+3. - - _Tp** __nstart = this->_M_map + (this->_M_map_size - __num_nodes) / 2; - _Tp** __nfinish = __nstart + __num_nodes; + void + _Deque_base<_Tp,_Alloc>::_M_initialize_map(size_t __num_elements) + { + size_t __num_nodes = __num_elements / __deque_buf_size(sizeof(_Tp)) + 1; - try - { _M_create_nodes(__nstart, __nfinish); } - catch(...) - { - _M_deallocate_map(this->_M_map, this->_M_map_size); - this->_M_map = 0; - this->_M_map_size = 0; - __throw_exception_again; - } - - _M_start._M_set_node(__nstart); - _M_finish._M_set_node(__nfinish - 1); - _M_start._M_cur = _M_start._M_first; - _M_finish._M_cur = _M_finish._M_first + - __num_elements % __deque_buf_size(sizeof(_Tp)); - } + this->_M_map_size = std::max((size_t) _S_initial_map_size, + __num_nodes + 2); + this->_M_map = _M_allocate_map(this->_M_map_size); + + // For "small" maps (needing less than _M_map_size nodes), allocation + // starts in the middle elements and grows outwards. So nstart may be + // the beginning of _M_map, but for small maps it may be as far in as + // _M_map+3. + + _Tp** __nstart = this->_M_map + (this->_M_map_size - __num_nodes) / 2; + _Tp** __nfinish = __nstart + __num_nodes; + + try + { _M_create_nodes(__nstart, __nfinish); } + catch(...) + { + _M_deallocate_map(this->_M_map, this->_M_map_size); + this->_M_map = 0; + this->_M_map_size = 0; + __throw_exception_again; + } + + _M_start._M_set_node(__nstart); + _M_finish._M_set_node(__nfinish - 1); + _M_start._M_cur = _M_start._M_first; + _M_finish._M_cur = _M_finish._M_first + __num_elements + % __deque_buf_size(sizeof(_Tp)); + } template - void _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) - { - _Tp** __cur; - try - { - for (__cur = __nstart; __cur < __nfinish; ++__cur) - *__cur = this->_M_allocate_node(); - } - catch(...) - { - _M_destroy_nodes(__nstart, __cur); - __throw_exception_again; - } - } + void + _Deque_base<_Tp,_Alloc>::_M_create_nodes(_Tp** __nstart, _Tp** __nfinish) + { + _Tp** __cur; + try + { + for (__cur = __nstart; __cur < __nfinish; ++__cur) + *__cur = this->_M_allocate_node(); + } + catch(...) + { + _M_destroy_nodes(__nstart, __cur); + __throw_exception_again; + } + } template - void - _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) - { - for (_Tp** __n = __nstart; __n < __nfinish; ++__n) - _M_deallocate_node(*__n); - } - + void + _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) + { + for (_Tp** __n = __nstart; __n < __nfinish; ++__n) + _M_deallocate_node(*__n); + } /** * @brief A standard container using fixed-size memory allocation and @@ -567,820 +571,851 @@ namespace __gnu_norm */ template > class deque : protected _Deque_base<_Tp, _Alloc> - { - // concept requirements - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - - typedef _Deque_base<_Tp, _Alloc> _Base; - - public: - typedef _Tp value_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef typename _Base::iterator iterator; - typedef typename _Base::const_iterator const_iterator; - typedef std::reverse_iterator const_reverse_iterator; - typedef std::reverse_iterator reverse_iterator; - typedef value_type& reference; - typedef const value_type& const_reference; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef typename _Base::allocator_type allocator_type; - - protected: - typedef pointer* _Map_pointer; - static size_t _S_buffer_size() { return __deque_buf_size(sizeof(_Tp)); } - - // Functions controlling memory layout, and nothing else. - using _Base::_M_initialize_map; - using _Base::_M_create_nodes; - using _Base::_M_destroy_nodes; - using _Base::_M_allocate_node; - using _Base::_M_deallocate_node; - using _Base::_M_allocate_map; - using _Base::_M_deallocate_map; - - /** @if maint - * A total of four data members accumulated down the heirarchy. - * @endif - */ - using _Base::_M_map; - using _Base::_M_map_size; - using _Base::_M_start; - using _Base::_M_finish; - - public: - // [23.2.1.1] construct/copy/destroy - // (assign() and get_allocator() are also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - explicit - deque(const allocator_type& __a = allocator_type()) + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + + typedef _Deque_base<_Tp, _Alloc> _Base; + + public: + typedef _Tp value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef typename _Base::iterator iterator; + typedef typename _Base::const_iterator const_iterator; + typedef std::reverse_iterator const_reverse_iterator; + typedef std::reverse_iterator reverse_iterator; + typedef value_type& reference; + typedef const value_type& const_reference; + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef typename _Base::allocator_type allocator_type; + + protected: + typedef pointer* _Map_pointer; + + static size_t _S_buffer_size() + { return __deque_buf_size(sizeof(_Tp)); } + + // Functions controlling memory layout, and nothing else. + using _Base::_M_initialize_map; + using _Base::_M_create_nodes; + using _Base::_M_destroy_nodes; + using _Base::_M_allocate_node; + using _Base::_M_deallocate_node; + using _Base::_M_allocate_map; + using _Base::_M_deallocate_map; + + /** @if maint + * A total of four data members accumulated down the heirarchy. + * @endif + */ + using _Base::_M_map; + using _Base::_M_map_size; + using _Base::_M_start; + using _Base::_M_finish; + + public: + // [23.2.1.1] construct/copy/destroy + // (assign() and get_allocator() are also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + explicit + deque(const allocator_type& __a = allocator_type()) : _Base(__a, 0) {} - /** - * @brief Create a %deque with copies of an exemplar element. - * @param n The number of elements to initially create. - * @param value An element to copy. - * - * This constructor fills the %deque with @a n copies of @a value. - */ - deque(size_type __n, const value_type& __value, - const allocator_type& __a = allocator_type()) + /** + * @brief Create a %deque with copies of an exemplar element. + * @param n The number of elements to initially create. + * @param value An element to copy. + * + * This constructor fills the %deque with @a n copies of @a value. + */ + deque(size_type __n, const value_type& __value, + const allocator_type& __a = allocator_type()) : _Base(__a, __n) { _M_fill_initialize(__value); } - /** - * @brief Create a %deque with default elements. - * @param n The number of elements to initially create. - * - * This constructor fills the %deque with @a n copies of a - * default-constructed element. - */ - explicit - deque(size_type __n) + /** + * @brief Create a %deque with default elements. + * @param n The number of elements to initially create. + * + * This constructor fills the %deque with @a n copies of a + * default-constructed element. + */ + explicit + deque(size_type __n) : _Base(allocator_type(), __n) { _M_fill_initialize(value_type()); } - /** - * @brief %Deque copy constructor. - * @param x A %deque of identical element and allocator types. - * - * The newly-created %deque uses a copy of the allocation object used - * by @a x. - */ - deque(const deque& __x) + /** + * @brief %Deque copy constructor. + * @param x A %deque of identical element and allocator types. + * + * The newly-created %deque uses a copy of the allocation object used + * by @a x. + */ + deque(const deque& __x) : _Base(__x.get_allocator(), __x.size()) { std::uninitialized_copy(__x.begin(), __x.end(), this->_M_start); } - /** - * @brief Builds a %deque from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %deque consisting of copies of the elements from [first,last). - * - * If the iterators are forward, bidirectional, or random-access, then - * this will call the elements' copy constructor N times (where N is - * distance(first,last)) and do no memory reallocation. But if only - * input iterators are used, then this will do at most 2N calls to the - * copy constructor, and logN memory reallocations. - */ - template - deque(_InputIterator __first, _InputIterator __last, - const allocator_type& __a = allocator_type()) - : _Base(__a) + /** + * @brief Builds a %deque from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %deque consisting of copies of the elements from [first, + * last). + * + * If the iterators are forward, bidirectional, or random-access, then + * this will call the elements' copy constructor N times (where N is + * distance(first,last)) and do no memory reallocation. But if only + * input iterators are used, then this will do at most 2N calls to the + * copy constructor, and logN memory reallocations. + */ + template + deque(_InputIterator __first, _InputIterator __last, + const allocator_type& __a = allocator_type()) + : _Base(__a) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_initialize_dispatch(__first, __last, _Integral()); + } + + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + ~deque() + { std::_Destroy(this->_M_start, this->_M_finish); } + + /** + * @brief %Deque assignment operator. + * @param x A %deque of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + deque& + operator=(const deque& __x); + + /** + * @brief Assigns a given value to a %deque. + * @param n Number of elements to be assigned. + * @param val Value to be assigned. + * + * This function fills a %deque with @a n copies of the given value. + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements assigned. + * Old data may be lost. + */ + void + assign(size_type __n, const value_type& __val) + { _M_fill_assign(__n, __val); } + + /** + * @brief Assigns a range to a %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function fills a %deque with copies of the elements in the + * range [first,last). + * + * Note that the assignment completely changes the %deque and that the + * resulting %deque's size is the same as the number of elements + * assigned. Old data may be lost. + */ + template + void + assign(_InputIterator __first, _InputIterator __last) + { + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_assign_dispatch(__first, __last, _Integral()); + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _Base::get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first element in the + * %deque. Iteration is done in ordinary element order. + */ + iterator + begin() + { return this->_M_start; } + + /** + * Returns a read-only (constant) iterator that points to the first + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + begin() const + { return this->_M_start; } + + /** + * Returns a read/write iterator that points one past the last element in + * the %deque. Iteration is done in ordinary element order. + */ + iterator + end() + { return this->_M_finish; } + + /** + * Returns a read-only (constant) iterator that points one past the last + * element in the %deque. Iteration is done in ordinary element order. + */ + const_iterator + end() const + { return this->_M_finish; } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %deque. Iteration is done in reverse element order. + */ + reverse_iterator + rbegin() + { return reverse_iterator(this->_M_finish); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last element in the %deque. Iteration is done in reverse element + * order. + */ + const_reverse_iterator + rbegin() const + { return const_reverse_iterator(this->_M_finish); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first element in the %deque. Iteration is done in reverse element + * order. + */ + reverse_iterator + rend() { return reverse_iterator(this->_M_start); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first element in the %deque. Iteration is done in reverse + * element order. + */ + const_reverse_iterator + rend() const + { return const_reverse_iterator(this->_M_start); } + + // [23.2.1.2] capacity + /** Returns the number of elements in the %deque. */ + size_type + size() const + { return this->_M_finish - this->_M_start; } + + /** Returns the size() of the largest possible %deque. */ + size_type + max_size() const + { return size_type(-1); } + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * @param x Data with which new elements should be populated. + * + * This function will %resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are populated with given data. + */ + void + resize(size_type __new_size, const value_type& __x) { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_initialize_dispatch(__first, __last, _Integral()); + const size_type __len = size(); + if (__new_size < __len) + erase(this->_M_start + __new_size, this->_M_finish); + else + insert(this->_M_finish, __new_size - __len, __x); } - - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - ~deque() { std::_Destroy(this->_M_start, this->_M_finish); } - - /** - * @brief %Deque assignment operator. - * @param x A %deque of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - deque& - operator=(const deque& __x); - - /** - * @brief Assigns a given value to a %deque. - * @param n Number of elements to be assigned. - * @param val Value to be assigned. - * - * This function fills a %deque with @a n copies of the given value. - * Note that the assignment completely changes the %deque and that the - * resulting %deque's size is the same as the number of elements assigned. - * Old data may be lost. - */ - void - assign(size_type __n, const value_type& __val) { _M_fill_assign(__n, __val); } - - /** - * @brief Assigns a range to a %deque. - * @param first An input iterator. - * @param last An input iterator. - * - * This function fills a %deque with copies of the elements in the - * range [first,last). - * - * Note that the assignment completely changes the %deque and that the - * resulting %deque's size is the same as the number of elements assigned. - * Old data may be lost. - */ - template + + /** + * @brief Resizes the %deque to the specified number of elements. + * @param new_size Number of elements the %deque should contain. + * + * This function will resize the %deque to the specified number of + * elements. If the number is smaller than the %deque's current size the + * %deque is truncated, otherwise the %deque is extended and new elements + * are default-constructed. + */ void - assign(_InputIterator __first, _InputIterator __last) + resize(size_type new_size) + { resize(new_size, value_type()); } + + /** + * Returns true if the %deque is empty. (Thus begin() would equal end().) + */ + bool + empty() const + { return this->_M_finish == this->_M_start; } + + // element access + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + reference + operator[](size_type __n) + { return this->_M_start[difference_type(__n)]; } + + /** + * @brief Subscript access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * + * This operator allows for easy, array-style, data access. + * Note that data access with this operator is unchecked and out_of_range + * lookups are not defined. (For checked lookups see at().) + */ + const_reference + operator[](size_type __n) const + { return this->_M_start[difference_type(__n)]; } + + protected: + /// @if maint Safety check used only from at(). @endif + void + _M_range_check(size_type __n) const { - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_assign_dispatch(__first, __last, _Integral()); + if (__n >= this->size()) + __throw_out_of_range(__N("deque::_M_range_check")); } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _Base::get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first element in the - * %deque. Iteration is done in ordinary element order. - */ - iterator - begin() { return this->_M_start; } - - /** - * Returns a read-only (constant) iterator that points to the first element - * in the %deque. Iteration is done in ordinary element order. - */ - const_iterator - begin() const { return this->_M_start; } - - /** - * Returns a read/write iterator that points one past the last element in - * the %deque. Iteration is done in ordinary element order. - */ - iterator - end() { return this->_M_finish; } - - /** - * Returns a read-only (constant) iterator that points one past the last - * element in the %deque. Iteration is done in ordinary element order. - */ - const_iterator - end() const { return this->_M_finish; } - - /** - * Returns a read/write reverse iterator that points to the last element in - * the %deque. Iteration is done in reverse element order. - */ - reverse_iterator - rbegin() { return reverse_iterator(this->_M_finish); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * element in the %deque. Iteration is done in reverse element order. - */ - const_reverse_iterator - rbegin() const { return const_reverse_iterator(this->_M_finish); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first element in the %deque. Iteration is done in reverse element - * order. - */ - reverse_iterator - rend() { return reverse_iterator(this->_M_start); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first element in the %deque. Iteration is done in reverse - * element order. - */ - const_reverse_iterator - rend() const { return const_reverse_iterator(this->_M_start); } - - // [23.2.1.2] capacity - /** Returns the number of elements in the %deque. */ - size_type - size() const { return this->_M_finish - this->_M_start; } - - /** Returns the size() of the largest possible %deque. */ - size_type - max_size() const { return size_type(-1); } - - /** - * @brief Resizes the %deque to the specified number of elements. - * @param new_size Number of elements the %deque should contain. - * @param x Data with which new elements should be populated. - * - * This function will %resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are populated with given data. - */ - void - resize(size_type __new_size, const value_type& __x) - { - const size_type __len = size(); - if (__new_size < __len) - erase(this->_M_start + __new_size, this->_M_finish); - else - insert(this->_M_finish, __new_size - __len, __x); - } - - /** - * @brief Resizes the %deque to the specified number of elements. - * @param new_size Number of elements the %deque should contain. - * - * This function will resize the %deque to the specified number of - * elements. If the number is smaller than the %deque's current size the - * %deque is truncated, otherwise the %deque is extended and new elements - * are default-constructed. - */ - void - resize(size_type new_size) { resize(new_size, value_type()); } - - /** - * Returns true if the %deque is empty. (Thus begin() would equal end().) - */ - bool empty() const { return this->_M_finish == this->_M_start; } - - // element access - /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read/write reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) - */ - reference - operator[](size_type __n) { return this->_M_start[difference_type(__n)]; } - - /** - * @brief Subscript access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read-only (constant) reference to data. - * - * This operator allows for easy, array-style, data access. - * Note that data access with this operator is unchecked and out_of_range - * lookups are not defined. (For checked lookups see at().) - */ - const_reference - operator[](size_type __n) const { - return this->_M_start[difference_type(__n)]; - } - - protected: - /// @if maint Safety check used only from at(). @endif - void - _M_range_check(size_type __n) const - { - if (__n >= this->size()) - __throw_out_of_range(__N("deque::_M_range_check")); - } - - public: - /** - * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read/write reference to data. - * @throw std::out_of_range If @a n is an invalid index. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the deque. The function throws - * out_of_range if the check fails. - */ - reference - at(size_type __n) { _M_range_check(__n); return (*this)[__n]; } - - /** - * @brief Provides access to the data contained in the %deque. - * @param n The index of the element for which data should be accessed. - * @return Read-only (constant) reference to data. - * @throw std::out_of_range If @a n is an invalid index. - * - * This function provides for safer data access. The parameter is first - * checked that it is in the range of the deque. The function throws - * out_of_range if the check fails. - */ - const_reference - at(size_type __n) const { _M_range_check(__n); return (*this)[__n]; } - - /** - * Returns a read/write reference to the data at the first element of the - * %deque. - */ - reference - front() { return *this->_M_start; } - - /** - * Returns a read-only (constant) reference to the data at the first - * element of the %deque. - */ - const_reference - front() const { return *this->_M_start; } - - /** - * Returns a read/write reference to the data at the last element of the - * %deque. - */ - reference - back() - { - iterator __tmp = this->_M_finish; - --__tmp; - return *__tmp; - } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the %deque. - */ - const_reference - back() const - { - const_iterator __tmp = this->_M_finish; - --__tmp; - return *__tmp; - } - - // [23.2.1.2] modifiers - /** - * @brief Add data to the front of the %deque. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the front of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. - */ - void - push_front(const value_type& __x) - { - if (this->_M_start._M_cur != this->_M_start._M_first) { - std::_Construct(this->_M_start._M_cur - 1, __x); - --this->_M_start._M_cur; - } - else - _M_push_front_aux(__x); - } - - /** - * @brief Add data to the end of the %deque. - * @param x Data to be added. - * - * This is a typical stack operation. The function creates an element at - * the end of the %deque and assigns the given data to it. Due to the - * nature of a %deque this operation can be done in constant time. - */ - void - push_back(const value_type& __x) - { - if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) { - std::_Construct(this->_M_finish._M_cur, __x); - ++this->_M_finish._M_cur; - } - else - _M_push_back_aux(__x); - } - - /** - * @brief Removes first element. - * - * This is a typical stack operation. It shrinks the %deque by one. - * - * Note that no data is returned, and if the first element's data is - * needed, it should be retrieved before pop_front() is called. - */ - void - pop_front() - { - if (this->_M_start._M_cur != this->_M_start._M_last - 1) { - std::_Destroy(this->_M_start._M_cur); - ++this->_M_start._M_cur; - } - else - _M_pop_front_aux(); - } - - /** - * @brief Removes last element. - * - * This is a typical stack operation. It shrinks the %deque by one. - * - * Note that no data is returned, and if the last element's data is - * needed, it should be retrieved before pop_back() is called. - */ - void - pop_back() - { - if (this->_M_finish._M_cur != this->_M_finish._M_first) { - --this->_M_finish._M_cur; - std::_Destroy(this->_M_finish._M_cur); - } - else - _M_pop_back_aux(); - } - - /** - * @brief Inserts given value into %deque before specified iterator. - * @param position An iterator into the %deque. - * @param x Data to be inserted. - * @return An iterator that points to the inserted data. - * - * This function will insert a copy of the given value before the specified - * location. - */ - iterator - insert(iterator position, const value_type& __x); - - /** - * @brief Inserts a number of copies of given data into the %deque. - * @param position An iterator into the %deque. - * @param n Number of elements to be inserted. - * @param x Data to be inserted. - * - * This function will insert a specified number of copies of the given data - * before the location specified by @a position. - */ - void - insert(iterator __position, size_type __n, const value_type& __x) - { _M_fill_insert(__position, __n, __x); } - - /** - * @brief Inserts a range into the %deque. - * @param position An iterator into the %deque. - * @param first An input iterator. - * @param last An input iterator. - * - * This function will insert copies of the data in the range [first,last) - * into the %deque before the location specified by @a pos. This is - * known as "range insert." - */ - template - void - insert(iterator __position, _InputIterator __first, _InputIterator __last) + + public: + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read/write reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + reference + at(size_type __n) + { _M_range_check(__n); return (*this)[__n]; } + + /** + * @brief Provides access to the data contained in the %deque. + * @param n The index of the element for which data should be accessed. + * @return Read-only (constant) reference to data. + * @throw std::out_of_range If @a n is an invalid index. + * + * This function provides for safer data access. The parameter is first + * checked that it is in the range of the deque. The function throws + * out_of_range if the check fails. + */ + const_reference + at(size_type __n) const { - // Check whether it's an integral type. If so, it's not an iterator. - typedef typename _Is_integer<_InputIterator>::_Integral _Integral; - _M_insert_dispatch(__position, __first, __last, _Integral()); + _M_range_check(__n); + return (*this)[__n]; } - - /** - * @brief Remove element at given position. - * @param position Iterator pointing to element to be erased. - * @return An iterator pointing to the next element (or end()). - * - * This function will erase the element at the given position and thus - * shorten the %deque by one. - * - * The user is cautioned that - * this function only erases the element, and that if the element is itself - * a pointer, the pointed-to memory is not touched in any way. Managing - * the pointer is the user's responsibilty. - */ - iterator - erase(iterator __position); - - /** - * @brief Remove a range of elements. - * @param first Iterator pointing to the first element to be erased. - * @param last Iterator pointing to one past the last element to be - * erased. - * @return An iterator pointing to the element pointed to by @a last - * prior to erasing (or end()). - * - * This function will erase the elements in the range [first,last) and - * shorten the %deque accordingly. - * - * The user is cautioned that - * this function only erases the elements, and that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - iterator - erase(iterator __first, iterator __last); - - /** - * @brief Swaps data with another %deque. - * @param x A %deque of the same element and allocator types. - * - * This exchanges the elements between two deques in constant time. - * (Four pointers, so it should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(d1,d2) will feed to this function. - */ - void - swap(deque& __x) - { - std::swap(this->_M_start, __x._M_start); - std::swap(this->_M_finish, __x._M_finish); - std::swap(this->_M_map, __x._M_map); - std::swap(this->_M_map_size, __x._M_map_size); - } - - /** - * Erases all the elements. Note that this function only erases the - * elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void clear(); - - protected: - // Internal constructor functions follow. - - // called by the range constructor to implement [23.1.1]/9 - template - void - _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + + /** + * Returns a read/write reference to the data at the first element of the + * %deque. + */ + reference + front() + { return *this->_M_start; } + + /** + * Returns a read-only (constant) reference to the data at the first + * element of the %deque. + */ + const_reference + front() const + { return *this->_M_start; } + + /** + * Returns a read/write reference to the data at the last element of the + * %deque. + */ + reference + back() { - _M_initialize_map(__n); - _M_fill_initialize(__x); + iterator __tmp = this->_M_finish; + --__tmp; + return *__tmp; } - - // called by the range constructor to implement [23.1.1]/9 - template - void - _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, - __false_type) + + /** + * Returns a read-only (constant) reference to the data at the last + * element of the %deque. + */ + const_reference + back() const { - typedef typename iterator_traits<_InputIterator>::iterator_category - _IterCategory; - _M_range_initialize(__first, __last, _IterCategory()); + const_iterator __tmp = this->_M_finish; + --__tmp; + return *__tmp; } - - // called by the second initialize_dispatch above - //@{ - /** - * @if maint - * @brief Fills the deque with whatever is in [first,last). - * @param first An input iterator. - * @param last An input iterator. - * @return Nothing. - * - * If the iterators are actually forward iterators (or better), then the - * memory layout can be done all at once. Else we move forward using - * push_back on each value from the iterator. - * @endif - */ - template + + // [23.2.1.2] modifiers + /** + * @brief Add data to the front of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the front of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ void - _M_range_initialize(_InputIterator __first, _InputIterator __last, - input_iterator_tag); - - // called by the second initialize_dispatch above - template - void - _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag); - //@} - - /** - * @if maint - * @brief Fills the %deque with copies of value. - * @param value Initial value. - * @return Nothing. - * @pre _M_start and _M_finish have already been initialized, but none of - * the %deque's elements have yet been constructed. - * - * This function is called only when the user provides an explicit size - * (with or without an explicit exemplar value). - * @endif - */ - void - _M_fill_initialize(const value_type& __value); - - - // Internal assign functions follow. The *_aux functions do the actual - // assignment work for the range versions. - - // called by the range assign to implement [23.1.1]/9 - template - void - _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + push_front(const value_type& __x) { - _M_fill_assign(static_cast(__n), - static_cast(__val)); + if (this->_M_start._M_cur != this->_M_start._M_first) + { + std::_Construct(this->_M_start._M_cur - 1, __x); + --this->_M_start._M_cur; + } + else + _M_push_front_aux(__x); } - - // called by the range assign to implement [23.1.1]/9 - template + + /** + * @brief Add data to the end of the %deque. + * @param x Data to be added. + * + * This is a typical stack operation. The function creates an element at + * the end of the %deque and assigns the given data to it. Due to the + * nature of a %deque this operation can be done in constant time. + */ void - _M_assign_dispatch(_InputIterator __first, _InputIterator __last, __false_type) + push_back(const value_type& __x) { - typedef typename iterator_traits<_InputIterator>::iterator_category - _IterCategory; - _M_assign_aux(__first, __last, _IterCategory()); + if (this->_M_finish._M_cur != this->_M_finish._M_last - 1) + { + std::_Construct(this->_M_finish._M_cur, __x); + ++this->_M_finish._M_cur; + } + else + _M_push_back_aux(__x); } - // called by the second assign_dispatch above - template + /** + * @brief Removes first element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the first element's data is + * needed, it should be retrieved before pop_front() is called. + */ void - _M_assign_aux(_InputIterator __first, _InputIterator __last, - input_iterator_tag); - - // called by the second assign_dispatch above - template - void - _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, - forward_iterator_tag) + pop_front() { - size_type __len = std::distance(__first, __last); - if (__len > size()) { - _ForwardIterator __mid = __first; - std::advance(__mid, size()); - std::copy(__first, __mid, begin()); - insert(end(), __mid, __last); - } - else - erase(std::copy(__first, __last, begin()), end()); + if (this->_M_start._M_cur != this->_M_start._M_last - 1) + { + std::_Destroy(this->_M_start._M_cur); + ++this->_M_start._M_cur; + } + else + _M_pop_front_aux(); } - - // Called by assign(n,t), and the range assign when it turns out to be the - // same thing. - void - _M_fill_assign(size_type __n, const value_type& __val) - { - if (__n > size()) + + /** + * @brief Removes last element. + * + * This is a typical stack operation. It shrinks the %deque by one. + * + * Note that no data is returned, and if the last element's data is + * needed, it should be retrieved before pop_back() is called. + */ + void + pop_back() { - std::fill(begin(), end(), __val); - insert(end(), __n - size(), __val); + if (this->_M_finish._M_cur != this->_M_finish._M_first) + { + --this->_M_finish._M_cur; + std::_Destroy(this->_M_finish._M_cur); + } + else + _M_pop_back_aux(); } - else + + /** + * @brief Inserts given value into %deque before specified iterator. + * @param position An iterator into the %deque. + * @param x Data to be inserted. + * @return An iterator that points to the inserted data. + * + * This function will insert a copy of the given value before the + * specified location. + */ + iterator + insert(iterator position, const value_type& __x); + + /** + * @brief Inserts a number of copies of given data into the %deque. + * @param position An iterator into the %deque. + * @param n Number of elements to be inserted. + * @param x Data to be inserted. + * + * This function will insert a specified number of copies of the given + * data before the location specified by @a position. + */ + void + insert(iterator __position, size_type __n, const value_type& __x) + { _M_fill_insert(__position, __n, __x); } + + /** + * @brief Inserts a range into the %deque. + * @param position An iterator into the %deque. + * @param first An input iterator. + * @param last An input iterator. + * + * This function will insert copies of the data in the range [first,last) + * into the %deque before the location specified by @a pos. This is + * known as "range insert." + */ + template + void + insert(iterator __position, _InputIterator __first, + _InputIterator __last) + { + // Check whether it's an integral type. If so, it's not an iterator. + typedef typename _Is_integer<_InputIterator>::_Integral _Integral; + _M_insert_dispatch(__position, __first, __last, _Integral()); + } + + /** + * @brief Remove element at given position. + * @param position Iterator pointing to element to be erased. + * @return An iterator pointing to the next element (or end()). + * + * This function will erase the element at the given position and thus + * shorten the %deque by one. + * + * The user is cautioned that + * this function only erases the element, and that if the element is + * itself a pointer, the pointed-to memory is not touched in any way. + * Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __position); + + /** + * @brief Remove a range of elements. + * @param first Iterator pointing to the first element to be erased. + * @param last Iterator pointing to one past the last element to be + * erased. + * @return An iterator pointing to the element pointed to by @a last + * prior to erasing (or end()). + * + * This function will erase the elements in the range [first,last) and + * shorten the %deque accordingly. + * + * The user is cautioned that + * this function only erases the elements, and that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + iterator + erase(iterator __first, iterator __last); + + /** + * @brief Swaps data with another %deque. + * @param x A %deque of the same element and allocator types. + * + * This exchanges the elements between two deques in constant time. + * (Four pointers, so it should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(d1,d2) will feed to this function. + */ + void + swap(deque& __x) { - erase(begin() + __n, end()); - std::fill(begin(), end(), __val); + std::swap(this->_M_start, __x._M_start); + std::swap(this->_M_finish, __x._M_finish); + std::swap(this->_M_map, __x._M_map); + std::swap(this->_M_map_size, __x._M_map_size); } - } + + /** + * Erases all the elements. Note that this function only erases the + * elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void clear(); + + protected: + // Internal constructor functions follow. + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_Integer __n, _Integer __x, __true_type) + { + _M_initialize_map(__n); + _M_fill_initialize(__x); + } + + // called by the range constructor to implement [23.1.1]/9 + template + void + _M_initialize_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_initialize(__first, __last, _IterCategory()); + } + // called by the second initialize_dispatch above + //@{ + /** + * @if maint + * @brief Fills the deque with whatever is in [first,last). + * @param first An input iterator. + * @param last An input iterator. + * @return Nothing. + * + * If the iterators are actually forward iterators (or better), then the + * memory layout can be done all at once. Else we move forward using + * push_back on each value from the iterator. + * @endif + */ + template + void + _M_range_initialize(_InputIterator __first, _InputIterator __last, + input_iterator_tag); - //@{ - /** - * @if maint - * @brief Helper functions for push_* and pop_*. - * @endif - */ - void _M_push_back_aux(const value_type&); - void _M_push_front_aux(const value_type&); - void _M_pop_back_aux(); - void _M_pop_front_aux(); - //@} - - - // Internal insert functions follow. The *_aux functions do the actual - // insertion work when all shortcuts fail. - - // called by the range insert to implement [23.1.1]/9 - template + // called by the second initialize_dispatch above + template + void + _M_range_initialize(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag); + //@} + + /** + * @if maint + * @brief Fills the %deque with copies of value. + * @param value Initial value. + * @return Nothing. + * @pre _M_start and _M_finish have already been initialized, but none of + * the %deque's elements have yet been constructed. + * + * This function is called only when the user provides an explicit size + * (with or without an explicit exemplar value). + * @endif + */ void - _M_insert_dispatch(iterator __pos, - _Integer __n, _Integer __x, __true_type) + _M_fill_initialize(const value_type& __value); + + // Internal assign functions follow. The *_aux functions do the actual + // assignment work for the range versions. + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_Integer __n, _Integer __val, __true_type) + { + _M_fill_assign(static_cast(__n), + static_cast(__val)); + } + + // called by the range assign to implement [23.1.1]/9 + template + void + _M_assign_dispatch(_InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_assign_aux(__first, __last, _IterCategory()); + } + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_InputIterator __first, _InputIterator __last, + input_iterator_tag); + + // called by the second assign_dispatch above + template + void + _M_assign_aux(_ForwardIterator __first, _ForwardIterator __last, + forward_iterator_tag) + { + const size_type __len = std::distance(__first, __last); + if (__len > size()) + { + _ForwardIterator __mid = __first; + std::advance(__mid, size()); + std::copy(__first, __mid, begin()); + insert(end(), __mid, __last); + } + else + erase(std::copy(__first, __last, begin()), end()); + } + + // Called by assign(n,t), and the range assign when it turns out to be the + // same thing. + void + _M_fill_assign(size_type __n, const value_type& __val) { - _M_fill_insert(__pos, static_cast(__n), - static_cast(__x)); + if (__n > size()) + { + std::fill(begin(), end(), __val); + insert(end(), __n - size(), __val); + } + else + { + erase(begin() + __n, end()); + std::fill(begin(), end(), __val); + } } - // called by the range insert to implement [23.1.1]/9 - template + //@{ + /** + * @if maint + * @brief Helper functions for push_* and pop_*. + * @endif + */ + void _M_push_back_aux(const value_type&); + void _M_push_front_aux(const value_type&); + void _M_pop_back_aux(); + void _M_pop_front_aux(); + //@} + + // Internal insert functions follow. The *_aux functions do the actual + // insertion work when all shortcuts fail. + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _Integer __n, _Integer __x, __true_type) + { + _M_fill_insert(__pos, static_cast(__n), + static_cast(__x)); + } + + // called by the range insert to implement [23.1.1]/9 + template + void + _M_insert_dispatch(iterator __pos, + _InputIterator __first, _InputIterator __last, + __false_type) + { + typedef typename iterator_traits<_InputIterator>::iterator_category + _IterCategory; + _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + } + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _InputIterator __first, + _InputIterator __last, input_iterator_tag); + + // called by the second insert_dispatch above + template + void + _M_range_insert_aux(iterator __pos, _ForwardIterator __first, + _ForwardIterator __last, forward_iterator_tag); + + // Called by insert(p,n,x), and the range insert when it turns out to be + // the same thing. Can use fill functions in optimal situations, + // otherwise passes off to insert_aux(p,n,x). void - _M_insert_dispatch(iterator __pos, - _InputIterator __first, _InputIterator __last, - __false_type) + _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); + + // called by insert(p,x) + iterator + _M_insert_aux(iterator __pos, const value_type& __x); + + // called by insert(p,n,x) via fill_insert + void + _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); + + // called by range_insert_aux for forward iterators + template + void + _M_insert_aux(iterator __pos, + _ForwardIterator __first, _ForwardIterator __last, + size_type __n); + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the previous internal insert + * functions. + * @endif + */ + iterator + _M_reserve_elements_at_front(size_type __n) { - typedef typename iterator_traits<_InputIterator>::iterator_category - _IterCategory; - _M_range_insert_aux(__pos, __first, __last, _IterCategory()); + const size_type __vacancies = this->_M_start._M_cur + - this->_M_start._M_first; + if (__n > __vacancies) + _M_new_elements_at_front(__n - __vacancies); + return this->_M_start - difference_type(__n); + } + + iterator + _M_reserve_elements_at_back(size_type __n) + { + const size_type __vacancies = (this->_M_finish._M_last + - this->_M_finish._M_cur) - 1; + if (__n > __vacancies) + _M_new_elements_at_back(__n - __vacancies); + return this->_M_finish + difference_type(__n); + } + + void + _M_new_elements_at_front(size_type __new_elements); + + void + _M_new_elements_at_back(size_type __new_elements); + //@} + + + //@{ + /** + * @if maint + * @brief Memory-handling helpers for the major %map. + * + * Makes sure the _M_map has space for new nodes. Does not actually add + * the nodes. Can invalidate _M_map pointers. (And consequently, %deque + * iterators.) + * @endif + */ + void + _M_reserve_map_at_back (size_type __nodes_to_add = 1) + { + if (__nodes_to_add + 1 > this->_M_map_size + - (this->_M_finish._M_node - this->_M_map)) + _M_reallocate_map(__nodes_to_add, false); } - // called by the second insert_dispatch above - template void - _M_range_insert_aux(iterator __pos, _InputIterator __first, - _InputIterator __last, input_iterator_tag); + _M_reserve_map_at_front (size_type __nodes_to_add = 1) + { + if (__nodes_to_add > size_type(this->_M_start._M_node - this->_M_map)) + _M_reallocate_map(__nodes_to_add, true); + } - // called by the second insert_dispatch above - template void - _M_range_insert_aux(iterator __pos, _ForwardIterator __first, - _ForwardIterator __last, forward_iterator_tag); - - // Called by insert(p,n,x), and the range insert when it turns out to be - // the same thing. Can use fill functions in optimal situations, otherwise - // passes off to insert_aux(p,n,x). - void - _M_fill_insert(iterator __pos, size_type __n, const value_type& __x); - - // called by insert(p,x) - iterator - _M_insert_aux(iterator __pos, const value_type& __x); - - // called by insert(p,n,x) via fill_insert - void - _M_insert_aux(iterator __pos, size_type __n, const value_type& __x); - - // called by range_insert_aux for forward iterators - template - void - _M_insert_aux(iterator __pos, - _ForwardIterator __first, _ForwardIterator __last, - size_type __n); - - //@{ - /** - * @if maint - * @brief Memory-handling helpers for the previous internal insert - * functions. - * @endif - */ - iterator - _M_reserve_elements_at_front(size_type __n) - { - size_type __vacancies = this->_M_start._M_cur - this->_M_start._M_first; - if (__n > __vacancies) - _M_new_elements_at_front(__n - __vacancies); - return this->_M_start - difference_type(__n); - } - - iterator - _M_reserve_elements_at_back(size_type __n) - { - size_type __vacancies - = (this->_M_finish._M_last - this->_M_finish._M_cur) - 1; - if (__n > __vacancies) - _M_new_elements_at_back(__n - __vacancies); - return this->_M_finish + difference_type(__n); - } - - void - _M_new_elements_at_front(size_type __new_elements); - - void - _M_new_elements_at_back(size_type __new_elements); - //@} - - - //@{ - /** - * @if maint - * @brief Memory-handling helpers for the major %map. - * - * Makes sure the _M_map has space for new nodes. Does not actually add - * the nodes. Can invalidate _M_map pointers. (And consequently, %deque - * iterators.) - * @endif - */ - void - _M_reserve_map_at_back (size_type __nodes_to_add = 1) - { - if (__nodes_to_add + 1 - > this->_M_map_size - (this->_M_finish._M_node - this->_M_map)) - _M_reallocate_map(__nodes_to_add, false); - } - - void - _M_reserve_map_at_front (size_type __nodes_to_add = 1) - { - if (__nodes_to_add > size_type(this->_M_start._M_node - this->_M_map)) - _M_reallocate_map(__nodes_to_add, true); - } - - void - _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); - //@} - }; + _M_reallocate_map(size_type __nodes_to_add, bool __add_at_front); + //@} + }; /** @@ -1394,12 +1429,11 @@ namespace __gnu_norm * and if corresponding elements compare equal. */ template - inline bool operator==(const deque<_Tp, _Alloc>& __x, + inline bool + operator==(const deque<_Tp, _Alloc>& __x, const deque<_Tp, _Alloc>& __y) - { - return __x.size() == __y.size() && - std::equal(__x.begin(), __x.end(), __y.begin()); - } + { return __x.size() == __y.size() + && std::equal(__x.begin(), __x.end(), __y.begin()); } /** * @brief Deque ordering relation. @@ -1413,47 +1447,45 @@ namespace __gnu_norm * See std::lexicographical_compare() for how the determination is made. */ template - inline bool operator<(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) - { - return lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); - } + inline bool + operator<(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } /// Based on operator== template - inline bool operator!=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__x == __y); - } + inline bool + operator!=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x == __y); } /// Based on operator< template - inline bool operator>(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return __y < __x; - } + inline bool + operator>(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return __y < __x; } /// Based on operator< template - inline bool operator<=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__y < __x); - } + inline bool + operator<=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__y < __x); } /// Based on operator< template - inline bool operator>=(const deque<_Tp, _Alloc>& __x, - const deque<_Tp, _Alloc>& __y) { - return !(__x < __y); - } + inline bool + operator>=(const deque<_Tp, _Alloc>& __x, + const deque<_Tp, _Alloc>& __y) + { return !(__x < __y); } /// See std::deque::swap(). template - inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) - { - __x.swap(__y); - } + inline void + swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) + { __x.swap(__y); } } // namespace __gnu_norm #endif /* _DEQUE_H */ diff --git a/libstdc++-v3/include/bits/stl_function.h b/libstdc++-v3/include/bits/stl_function.h index 556104c714d..f7ddffc347c 100644 --- a/libstdc++-v3/include/bits/stl_function.h +++ b/libstdc++-v3/include/bits/stl_function.h @@ -1,6 +1,6 @@ // Functor implementations -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -63,668 +63,812 @@ namespace std { -// 20.3.1 base classes -/** @defgroup s20_3_1_base Functor Base Classes - * Function objects, or @e functors, are objects with an @c operator() - * defined and accessible. They can be passed as arguments to algorithm - * templates and used in place of a function pointer. Not only is the - * resulting expressiveness of the library increased, but the generated - * code can be more efficient than what you might write by hand. When we - * refer to "functors," then, generally we include function pointers in - * the description as well. - * - * Often, functors are only created as temporaries passed to algorithm - * calls, rather than being created as named variables. - * - * Two examples taken from the standard itself follow. To perform a - * by-element addition of two vectors @c a and @c b containing @c double, - * and put the result in @c a, use - * \code - * transform (a.begin(), a.end(), b.begin(), a.begin(), plus()); - * \endcode - * To negate every element in @c a, use - * \code - * transform(a.begin(), a.end(), a.begin(), negate()); - * \endcode - * The addition and negation functions will be inlined directly. - * - * The standard functiors are derived from structs named @c unary_function - * and @c binary_function. These two classes contain nothing but typedefs, - * to aid in generic (template) programming. If you write your own - * functors, you might consider doing the same. - * - * @{ -*/ -/** - * This is one of the @link s20_3_1_base functor base classes@endlink. -*/ -template -struct unary_function { - typedef _Arg argument_type; ///< @c argument_type is the type of the argument (no surprises here) - typedef _Result result_type; ///< @c result_type is the return type -}; + // 20.3.1 base classes + /** @defgroup s20_3_1_base Functor Base Classes + * Function objects, or @e functors, are objects with an @c operator() + * defined and accessible. They can be passed as arguments to algorithm + * templates and used in place of a function pointer. Not only is the + * resulting expressiveness of the library increased, but the generated + * code can be more efficient than what you might write by hand. When we + * refer to "functors," then, generally we include function pointers in + * the description as well. + * + * Often, functors are only created as temporaries passed to algorithm + * calls, rather than being created as named variables. + * + * Two examples taken from the standard itself follow. To perform a + * by-element addition of two vectors @c a and @c b containing @c double, + * and put the result in @c a, use + * \code + * transform (a.begin(), a.end(), b.begin(), a.begin(), plus()); + * \endcode + * To negate every element in @c a, use + * \code + * transform(a.begin(), a.end(), a.begin(), negate()); + * \endcode + * The addition and negation functions will be inlined directly. + * + * The standard functiors are derived from structs named @c unary_function + * and @c binary_function. These two classes contain nothing but typedefs, + * to aid in generic (template) programming. If you write your own + * functors, you might consider doing the same. + * + * @{ + */ + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct unary_function + { + typedef _Arg argument_type; ///< @c argument_type is the type of the + /// argument (no surprises here) -/** - * This is one of the @link s20_3_1_base functor base classes@endlink. -*/ -template -struct binary_function { - typedef _Arg1 first_argument_type; ///< the type of the first argument (no surprises here) - typedef _Arg2 second_argument_type; ///< the type of the second argument - typedef _Result result_type; ///< type of the return type -}; -/** @} */ + typedef _Result result_type; ///< @c result_type is the return type + }; -// 20.3.2 arithmetic -/** @defgroup s20_3_2_arithmetic Arithmetic Classes - * Because basic math often needs to be done during an algorithm, the library - * provides functors for those operations. See the documentation for - * @link s20_3_1_base the base classes@endlink for examples of their use. - * - * @{ -*/ -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct plus : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } -}; + /** + * This is one of the @link s20_3_1_base functor base classes@endlink. + */ + template + struct binary_function + { + typedef _Arg1 first_argument_type; ///< the type of the first argument + /// (no surprises here) -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct minus : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } -}; + typedef _Arg2 second_argument_type; ///< the type of the second argument + typedef _Result result_type; ///< type of the return type + }; + /** @} */ -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct multiplies : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } -}; + // 20.3.2 arithmetic + /** @defgroup s20_3_2_arithmetic Arithmetic Classes + * Because basic math often needs to be done during an algorithm, the library + * provides functors for those operations. See the documentation for + * @link s20_3_1_base the base classes@endlink for examples of their use. + * + * @{ + */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct plus : public binary_function<_Tp,_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x + __y; } + }; -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct divides : public binary_function<_Tp,_Tp,_Tp> { - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } -}; + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct minus : public binary_function<_Tp,_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x - __y; } + }; -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct modulus : public binary_function<_Tp,_Tp,_Tp> -{ - _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } -}; + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct multiplies : public binary_function<_Tp,_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x * __y; } + }; -/// One of the @link s20_3_2_arithmetic math functors@endlink. -template -struct negate : public unary_function<_Tp,_Tp> -{ - _Tp operator()(const _Tp& __x) const { return -__x; } -}; -/** @} */ + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct divides : public binary_function<_Tp,_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x / __y; } + }; -// 20.3.3 comparisons -/** @defgroup s20_3_3_comparisons Comparison Classes - * The library provides six wrapper functors for all the basic comparisons - * in C++, like @c <. - * - * @{ -*/ -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct equal_to : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } -}; + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct modulus : public binary_function<_Tp,_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x, const _Tp& __y) const + { return __x % __y; } + }; -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct not_equal_to : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } -}; + /// One of the @link s20_3_2_arithmetic math functors@endlink. + template + struct negate : public unary_function<_Tp,_Tp> + { + _Tp + operator()(const _Tp& __x) const + { return -__x; } + }; + /** @} */ -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct greater : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } -}; + // 20.3.3 comparisons + /** @defgroup s20_3_3_comparisons Comparison Classes + * The library provides six wrapper functors for all the basic comparisons + * in C++, like @c <. + * + * @{ + */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct equal_to : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x == __y; } + }; -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct less : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } -}; + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct not_equal_to : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x != __y; } + }; -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct greater_equal : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } -}; + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x > __y; } + }; -/// One of the @link s20_3_3_comparisons comparison functors@endlink. -template -struct less_equal : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } -}; -/** @} */ + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x < __y; } + }; -// 20.3.4 logical operations -/** @defgroup s20_3_4_logical Boolean Operations Classes - * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. - * - * @{ -*/ -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template -struct logical_and : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } -}; + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct greater_equal : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x >= __y; } + }; -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template -struct logical_or : public binary_function<_Tp,_Tp,bool> -{ - bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } -}; + /// One of the @link s20_3_3_comparisons comparison functors@endlink. + template + struct less_equal : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x <= __y; } + }; + /** @} */ + + // 20.3.4 logical operations + /** @defgroup s20_3_4_logical Boolean Operations Classes + * Here are wrapper functors for Boolean operations: @c &&, @c ||, and @c !. + * + * @{ + */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_and : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x && __y; } + }; -/// One of the @link s20_3_4_logical Boolean operations functors@endlink. -template -struct logical_not : public unary_function<_Tp,bool> -{ - bool operator()(const _Tp& __x) const { return !__x; } -}; -/** @} */ + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_or : public binary_function<_Tp,_Tp,bool> + { + bool + operator()(const _Tp& __x, const _Tp& __y) const + { return __x || __y; } + }; -// 20.3.5 negators -/** @defgroup s20_3_5_negators Negators - * The functions @c not1 and @c not2 each take a predicate functor - * and return an instance of @c unary_negate or - * @c binary_negate, respectively. These classes are functors whose - * @c operator() performs the stored predicate function and then returns - * the negation of the result. - * - * For example, given a vector of integers and a trivial predicate, - * \code - * struct IntGreaterThanThree - * : public std::unary_function - * { - * bool operator() (int x) { return x > 3; } - * }; - * - * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); - * \endcode - * The call to @c find_if will locate the first index (i) of @c v for which - * "!(v[i] > 3)" is true. - * - * The not1/unary_negate combination works on predicates taking a single - * argument. The not2/binary_negate combination works on predicates which - * take two arguments. - * - * @{ -*/ -/// One of the @link s20_3_5_negators negation functors@endlink. -template -class unary_negate - : public unary_function { -protected: - _Predicate _M_pred; -public: - explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} - bool operator()(const typename _Predicate::argument_type& __x) const { - return !_M_pred(__x); - } -}; + /// One of the @link s20_3_4_logical Boolean operations functors@endlink. + template + struct logical_not : public unary_function<_Tp,bool> + { + bool + operator()(const _Tp& __x) const + { return !__x; } + }; + /** @} */ -/// One of the @link s20_3_5_negators negation functors@endlink. -template -inline unary_negate<_Predicate> -not1(const _Predicate& __pred) -{ - return unary_negate<_Predicate>(__pred); -} + // 20.3.5 negators + /** @defgroup s20_3_5_negators Negators + * The functions @c not1 and @c not2 each take a predicate functor + * and return an instance of @c unary_negate or + * @c binary_negate, respectively. These classes are functors whose + * @c operator() performs the stored predicate function and then returns + * the negation of the result. + * + * For example, given a vector of integers and a trivial predicate, + * \code + * struct IntGreaterThanThree + * : public std::unary_function + * { + * bool operator() (int x) { return x > 3; } + * }; + * + * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); + * \endcode + * The call to @c find_if will locate the first index (i) of @c v for which + * "!(v[i] > 3)" is true. + * + * The not1/unary_negate combination works on predicates taking a single + * argument. The not2/binary_negate combination works on predicates which + * take two arguments. + * + * @{ + */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class unary_negate + : public unary_function + { + protected: + _Predicate _M_pred; + public: + explicit unary_negate(const _Predicate& __x) : _M_pred(__x) {} + + bool + operator()(const typename _Predicate::argument_type& __x) const + { return !_M_pred(__x); } + }; -/// One of the @link s20_3_5_negators negation functors@endlink. -template -class binary_negate - : public binary_function { -protected: - _Predicate _M_pred; -public: - explicit binary_negate(const _Predicate& __x) : _M_pred(__x) {} - bool operator()(const typename _Predicate::first_argument_type& __x, - const typename _Predicate::second_argument_type& __y) const - { - return !_M_pred(__x, __y); - } -}; + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline unary_negate<_Predicate> + not1(const _Predicate& __pred) + { return unary_negate<_Predicate>(__pred); } -/// One of the @link s20_3_5_negators negation functors@endlink. -template -inline binary_negate<_Predicate> -not2(const _Predicate& __pred) -{ - return binary_negate<_Predicate>(__pred); -} -/** @} */ + /// One of the @link s20_3_5_negators negation functors@endlink. + template + class binary_negate + : public binary_function + { + protected: + _Predicate _M_pred; + public: + explicit binary_negate(const _Predicate& __x) + : _M_pred(__x) { } -// 20.3.6 binders -/** @defgroup s20_3_6_binder Binder Classes - * Binders turn functions/functors with two arguments into functors with - * a single argument, storing an argument to be applied later. For - * example, an variable @c B of type @c binder1st is constructed from a functor - * @c f and an argument @c x. Later, B's @c operator() is called with a - * single argument @c y. The return value is the value of @c f(x,y). - * @c B can be "called" with various arguments (y1, y2, ...) and will in - * turn call @c f(x,y1), @c f(x,y2), ... - * - * The function @c bind1st is provided to save some typing. It takes the - * function and an argument as parameters, and returns an instance of - * @c binder1st. - * - * The type @c binder2nd and its creator function @c bind2nd do the same - * thing, but the stored argument is passed as the second parameter instead - * of the first, e.g., @c bind2nd(std::minus,1.3) will create a - * functor whose @c operator() accepts a floating-point number, subtracts - * 1.3 from it, and returns the result. (If @c bind1st had been used, - * the functor would perform "1.3 - x" instead. - * - * Creator-wrapper functions like @c bind1st are intended to be used in - * calling algorithms. Their return values will be temporary objects. - * (The goal is to not require you to type names like - * @c std::binder1st> for declaring a variable to hold the - * return value from @c bind1st(std::plus,5). - * - * These become more useful when combined with the composition functions. - * - * @{ -*/ -/// One of the @link s20_3_6_binder binder functors@endlink. -template -class binder1st - : public unary_function { -protected: - _Operation op; - typename _Operation::first_argument_type value; -public: - binder1st(const _Operation& __x, - const typename _Operation::first_argument_type& __y) - : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 109. Missing binders for non-const sequence elements - typename _Operation::result_type - operator()(typename _Operation::second_argument_type& __x) const { - return op(value, __x); - } -}; + bool + operator()(const typename _Predicate::first_argument_type& __x, + const typename _Predicate::second_argument_type& __y) const + { return !_M_pred(__x, __y); } + }; -/// One of the @link s20_3_6_binder binder functors@endlink. -template -inline binder1st<_Operation> -bind1st(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::first_argument_type _Arg1_type; - return binder1st<_Operation>(__fn, _Arg1_type(__x)); -} + /// One of the @link s20_3_5_negators negation functors@endlink. + template + inline binary_negate<_Predicate> + not2(const _Predicate& __pred) + { return binary_negate<_Predicate>(__pred); } + /** @} */ + + // 20.3.6 binders + /** @defgroup s20_3_6_binder Binder Classes + * Binders turn functions/functors with two arguments into functors with + * a single argument, storing an argument to be applied later. For + * example, an variable @c B of type @c binder1st is constructed from a + * functor @c f and an argument @c x. Later, B's @c operator() is called + * with a single argument @c y. The return value is the value of @c f(x,y). + * @c B can be "called" with various arguments (y1, y2, ...) and will in + * turn call @c f(x,y1), @c f(x,y2), ... + * + * The function @c bind1st is provided to save some typing. It takes the + * function and an argument as parameters, and returns an instance of + * @c binder1st. + * + * The type @c binder2nd and its creator function @c bind2nd do the same + * thing, but the stored argument is passed as the second parameter instead + * of the first, e.g., @c bind2nd(std::minus,1.3) will create a + * functor whose @c operator() accepts a floating-point number, subtracts + * 1.3 from it, and returns the result. (If @c bind1st had been used, + * the functor would perform "1.3 - x" instead. + * + * Creator-wrapper functions like @c bind1st are intended to be used in + * calling algorithms. Their return values will be temporary objects. + * (The goal is to not require you to type names like + * @c std::binder1st> for declaring a variable to hold the + * return value from @c bind1st(std::plus,5). + * + * These become more useful when combined with the composition functions. + * + * @{ + */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder1st + : public unary_function + { + protected: + _Operation op; + typename _Operation::first_argument_type value; + public: + binder1st(const _Operation& __x, + const typename _Operation::first_argument_type& __y) + : op(__x), value(__y) {} -/// One of the @link s20_3_6_binder binder functors@endlink. -template -class binder2nd - : public unary_function { -protected: - _Operation op; - typename _Operation::second_argument_type value; -public: - binder2nd(const _Operation& __x, - const typename _Operation::second_argument_type& __y) - : op(__x), value(__y) {} - typename _Operation::result_type - operator()(const typename _Operation::first_argument_type& __x) const { - return op(__x, value); - } - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 109. Missing binders for non-const sequence elements - typename _Operation::result_type - operator()(typename _Operation::first_argument_type& __x) const { - return op(__x, value); - } -}; + typename _Operation::result_type + operator()(const typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::second_argument_type& __x) const + { return op(value, __x); } + }; -/// One of the @link s20_3_6_binder binder functors@endlink. -template -inline binder2nd<_Operation> -bind2nd(const _Operation& __fn, const _Tp& __x) -{ - typedef typename _Operation::second_argument_type _Arg2_type; - return binder2nd<_Operation>(__fn, _Arg2_type(__x)); -} -/** @} */ - -// 20.3.7 adaptors pointers functions -/** @defgroup s20_3_7_adaptors Adaptors for pointers to functions - * The advantage of function objects over pointers to functions is that - * the objects in the standard library declare nested typedefs describing - * their argument and result types with uniform names (e.g., @c result_type - * from the base classes @c unary_function and @c binary_function). - * Sometimes those typedefs are required, not just optional. - * - * Adaptors are provided to turn pointers to unary (single-argument) and - * binary (double-argument) functions into function objects. The long-winded - * functor @c pointer_to_unary_function is constructed with a function - * pointer @c f, and its @c operator() called with argument @c x returns - * @c f(x). The functor @c pointer_to_binary_function does the same thing, - * but with a double-argument @c f and @c operator(). - * - * The function @c ptr_fun takes a pointer-to-function @c f and constructs - * an instance of the appropriate functor. - * - * @{ -*/ -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template -class pointer_to_unary_function : public unary_function<_Arg, _Result> { -protected: - _Result (*_M_ptr)(_Arg); -public: - pointer_to_unary_function() {} - explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) {} - _Result operator()(_Arg __x) const { return _M_ptr(__x); } -}; - -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template -inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) -{ - return pointer_to_unary_function<_Arg, _Result>(__x); -} - -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template -class pointer_to_binary_function : - public binary_function<_Arg1,_Arg2,_Result> { -protected: - _Result (*_M_ptr)(_Arg1, _Arg2); -public: - pointer_to_binary_function() {} - explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) - : _M_ptr(__x) {} - _Result operator()(_Arg1 __x, _Arg2 __y) const { - return _M_ptr(__x, __y); + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder1st<_Operation> + bind1st(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::first_argument_type _Arg1_type; + return binder1st<_Operation>(__fn, _Arg1_type(__x)); } -}; -/// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. -template -inline pointer_to_binary_function<_Arg1,_Arg2,_Result> -ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { - return pointer_to_binary_function<_Arg1,_Arg2,_Result>(__x); -} -/** @} */ + /// One of the @link s20_3_6_binder binder functors@endlink. + template + class binder2nd + : public unary_function + { + protected: + _Operation op; + typename _Operation::second_argument_type value; + public: + binder2nd(const _Operation& __x, + const typename _Operation::second_argument_type& __y) + : op(__x), value(__y) {} -template -struct _Identity : public unary_function<_Tp,_Tp> { - _Tp& operator()(_Tp& __x) const { return __x; } - const _Tp& operator()(const _Tp& __x) const { return __x; } -}; + typename _Operation::result_type + operator()(const typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 109. Missing binders for non-const sequence elements + typename _Operation::result_type + operator()(typename _Operation::first_argument_type& __x) const + { return op(__x, value); } + }; -template -struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { - typename _Pair::first_type& operator()(_Pair& __x) const { - return __x.first; - } - const typename _Pair::first_type& operator()(const _Pair& __x) const { - return __x.first; - } -}; + /// One of the @link s20_3_6_binder binder functors@endlink. + template + inline binder2nd<_Operation> + bind2nd(const _Operation& __fn, const _Tp& __x) + { + typedef typename _Operation::second_argument_type _Arg2_type; + return binder2nd<_Operation>(__fn, _Arg2_type(__x)); + } + /** @} */ + + // 20.3.7 adaptors pointers functions + /** @defgroup s20_3_7_adaptors Adaptors for pointers to functions + * The advantage of function objects over pointers to functions is that + * the objects in the standard library declare nested typedefs describing + * their argument and result types with uniform names (e.g., @c result_type + * from the base classes @c unary_function and @c binary_function). + * Sometimes those typedefs are required, not just optional. + * + * Adaptors are provided to turn pointers to unary (single-argument) and + * binary (double-argument) functions into function objects. The + * long-winded functor @c pointer_to_unary_function is constructed with a + * function pointer @c f, and its @c operator() called with argument @c x + * returns @c f(x). The functor @c pointer_to_binary_function does the same + * thing, but with a double-argument @c f and @c operator(). + * + * The function @c ptr_fun takes a pointer-to-function @c f and constructs + * an instance of the appropriate functor. + * + * @{ + */ + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_unary_function : public unary_function<_Arg, _Result> + { + protected: + _Result (*_M_ptr)(_Arg); + public: + pointer_to_unary_function() {} + + explicit pointer_to_unary_function(_Result (*__x)(_Arg)) + : _M_ptr(__x) {} -template -struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> -{ - typename _Pair::second_type& operator()(_Pair& __x) const { - return __x.second; - } - const typename _Pair::second_type& operator()(const _Pair& __x) const { - return __x.second; - } -}; + _Result + operator()(_Arg __x) const + { return _M_ptr(__x); } + }; -// 20.3.8 adaptors pointers members -/** @defgroup s20_3_8_memadaptors Adaptors for pointers to members - * There are a total of 16 = 2^4 function objects in this family. - * (1) Member functions taking no arguments vs member functions taking - * one argument. - * (2) Call through pointer vs call through reference. - * (3) Member function with void return type vs member function with - * non-void return type. - * (4) Const vs non-const member function. - * - * Note that choice (3) is nothing more than a workaround: according - * to the draft, compilers should handle void and non-void the same way. - * This feature is not yet widely implemented, though. You can only use - * member functions returning void if your compiler supports partial - * specialization. - * - * All of this complexity is in the function objects themselves. You can - * ignore it by using the helper function mem_fun and mem_fun_ref, - * which create whichever type of adaptor is appropriate. - * - * @{ -*/ -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun_t : public unary_function<_Tp*,_Ret> { -public: - explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} - _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } -private: - _Ret (_Tp::*_M_f)(); -}; + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_unary_function<_Arg, _Result> + ptr_fun(_Result (*__x)(_Arg)) + { return pointer_to_unary_function<_Arg, _Result>(__x); } -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun_t : public unary_function { -public: - explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} - _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } -private: - _Ret (_Tp::*_M_f)() const; -}; + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + class pointer_to_binary_function + : public binary_function<_Arg1, _Arg2, _Result> + { + protected: + _Result (*_M_ptr)(_Arg1, _Arg2); + public: + pointer_to_binary_function() {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun_ref_t : public unary_function<_Tp,_Ret> { -public: - explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {} - _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } -private: - _Ret (_Tp::*_M_f)(); -}; + explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) + : _M_ptr(__x) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> { -public: - explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {} - _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } -private: - _Ret (_Tp::*_M_f)() const; -}; + _Result + operator()(_Arg1 __x, _Arg2 __y) const + { return _M_ptr(__x, __y); } + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> { -public: - explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg); -}; + /// One of the @link s20_3_7_adaptors adaptors for function pointers@endlink. + template + inline pointer_to_binary_function<_Arg1, _Arg2, _Result> + ptr_fun(_Result (*__x)(_Arg1, _Arg2)) + { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } + /** @} */ + + template + struct _Identity : public unary_function<_Tp,_Tp> + { + _Tp& + operator()(_Tp& __x) const + { return __x; } + + const _Tp& + operator()(const _Tp& __x) const + { return __x; } + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun1_t : public binary_function { -public: - explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - _Ret operator()(const _Tp* __p, _Arg __x) const - { return (__p->*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg) const; -}; + template + struct _Select1st : public unary_function<_Pair, + typename _Pair::first_type> + { + typename _Pair::first_type& + operator()(_Pair& __x) const + { return __x.first; } + + const typename _Pair::first_type& + operator()(const _Pair& __x) const + { return __x.first; } + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { -public: - explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg); -}; + template + struct _Select2nd : public unary_function<_Pair, + typename _Pair::second_type> + { + typename _Pair::second_type& + operator()(_Pair& __x) const + { return __x.second; } + + const typename _Pair::second_type& + operator()(const _Pair& __x) const + { return __x.second; } + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun1_ref_t : public binary_function<_Tp,_Arg,_Ret> { -public: - explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } -private: - _Ret (_Tp::*_M_f)(_Arg) const; -}; + // 20.3.8 adaptors pointers members + /** @defgroup s20_3_8_memadaptors Adaptors for pointers to members + * There are a total of 16 = 2^4 function objects in this family. + * (1) Member functions taking no arguments vs member functions taking + * one argument. + * (2) Call through pointer vs call through reference. + * (3) Member function with void return type vs member function with + * non-void return type. + * (4) Const vs non-const member function. + * + * Note that choice (3) is nothing more than a workaround: according + * to the draft, compilers should handle void and non-void the same way. + * This feature is not yet widely implemented, though. You can only use + * member functions returning void if your compiler supports partial + * specialization. + * + * All of this complexity is in the function objects themselves. You can + * ignore it by using the helper function mem_fun and mem_fun_ref, + * which create whichever type of adaptor is appropriate. + * + * @{ + */ + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, _Ret> + { + public: + explicit mem_fun_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun_t : public unary_function<_Tp*,void> { -public: - explicit mem_fun_t(void (_Tp::*__pf)()) : _M_f(__pf) {} - void operator()(_Tp* __p) const { (__p->*_M_f)(); } -private: - void (_Tp::*_M_f)(); -}; + _Ret + operator()(_Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun_t : public unary_function { -public: - explicit const_mem_fun_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} - void operator()(const _Tp* __p) const { (__p->*_M_f)(); } -private: - void (_Tp::*_M_f)() const; -}; + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun_ref_t : public unary_function<_Tp,void> { -public: - explicit mem_fun_ref_t(void (_Tp::*__pf)()) : _M_f(__pf) {} - void operator()(_Tp& __r) const { (__r.*_M_f)(); } -private: - void (_Tp::*_M_f)(); -}; + _Ret + operator()(const _Tp* __p) const + { return (__p->*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun_ref_t : public unary_function<_Tp,void> { -public: - explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) : _M_f(__pf) {} - void operator()(const _Tp& __r) const { (__r.*_M_f)(); } -private: - void (_Tp::*_M_f)() const; -}; + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) + : _M_f(__pf) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun1_t : public binary_function<_Tp*,_Arg,void> { -public: - explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - void operator()(_Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg); -}; + _Ret + operator()(_Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> + { + public: + explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) + : _M_f(__pf) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun1_t - : public binary_function { -public: - explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - void operator()(const _Tp* __p, _Arg __x) const { (__p->*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg) const; -}; + _Ret + operator()(const _Tp& __r) const + { return (__r.*_M_f)(); } + private: + _Ret (_Tp::*_M_f)() const; + }; -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class mem_fun1_ref_t - : public binary_function<_Tp,_Arg,void> { -public: - explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) : _M_f(__pf) {} - void operator()(_Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg); -}; + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> + { + public: + explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} -/// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. -template -class const_mem_fun1_ref_t - : public binary_function<_Tp,_Arg,void> { -public: - explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) : _M_f(__pf) {} - void operator()(const _Tp& __r, _Arg __x) const { (__r.*_M_f)(__x); } -private: - void (_Tp::*_M_f)(_Arg) const; -}; + _Ret + operator()(_Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t : public binary_function + { + public: + explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} -// Mem_fun adaptor helper functions. There are only two: -// mem_fun and mem_fun_ref. + _Ret + operator()(const _Tp* __p, _Arg __x) const + { return (__p->*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; -template -inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)()) - { return mem_fun_t<_Ret,_Tp>(__f); } + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} -template -inline const_mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)() const) - { return const_mem_fun_t<_Ret,_Tp>(__f); } + _Ret + operator()(_Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg); + }; -template -inline mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)()) - { return mem_fun_ref_t<_Ret,_Tp>(__f); } + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> + { + public: + explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} -template -inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) - { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } + _Ret + operator()(const _Tp& __r, _Arg __x) const + { return (__r.*_M_f)(__x); } + private: + _Ret (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_t : public unary_function<_Tp*, void> + { + public: + explicit mem_fun_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} -template -inline mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) - { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + void + operator()(_Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_t : public unary_function + { + public: + explicit const_mem_fun_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} -template -inline const_mem_fun1_t<_Ret,_Tp,_Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) - { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + void + operator()(const _Tp* __p) const + { (__p->*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit mem_fun_ref_t(void (_Tp::*__pf)()) + : _M_f(__pf) {} -template -inline mem_fun1_ref_t<_Ret,_Tp,_Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) - { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + void + operator()(_Tp& __r) const + { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)(); + }; -template -inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> -mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) - { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun_ref_t : public unary_function<_Tp, void> + { + public: + explicit const_mem_fun_ref_t(void (_Tp::*__pf)() const) + : _M_f(__pf) {} -/** @} */ + void + operator()(const _Tp& __r) + const { (__r.*_M_f)(); } + private: + void (_Tp::*_M_f)() const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_t : public binary_function<_Tp*, _Arg, void> + { + public: + explicit mem_fun1_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_t + : public binary_function + { + public: + explicit const_mem_fun1_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp* __p, _Arg __x) const + { (__p->*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit mem_fun1_ref_t(void (_Tp::*__pf)(_Arg)) + : _M_f(__pf) {} + + void + operator()(_Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg); + }; + + /// One of the @link s20_3_8_memadaptors adaptors for member pointers@endlink. + template + class const_mem_fun1_ref_t + : public binary_function<_Tp, _Arg, void> + { + public: + explicit const_mem_fun1_ref_t(void (_Tp::*__pf)(_Arg) const) + : _M_f(__pf) {} + + void + operator()(const _Tp& __r, _Arg __x) const + { (__r.*_M_f)(__x); } + private: + void (_Tp::*_M_f)(_Arg) const; + }; + + // Mem_fun adaptor helper functions. There are only two: + // mem_fun and mem_fun_ref. + template + inline mem_fun_t<_Ret,_Tp> + mem_fun(_Ret (_Tp::*__f)()) + { return mem_fun_t<_Ret,_Tp>(__f); } + + template + inline const_mem_fun_t<_Ret,_Tp> + mem_fun(_Ret (_Tp::*__f)() const) + { return const_mem_fun_t<_Ret,_Tp>(__f); } + + template + inline mem_fun_ref_t<_Ret,_Tp> + mem_fun_ref(_Ret (_Tp::*__f)()) + { return mem_fun_ref_t<_Ret,_Tp>(__f); } + + template + inline const_mem_fun_ref_t<_Ret,_Tp> + mem_fun_ref(_Ret (_Tp::*__f)() const) + { return const_mem_fun_ref_t<_Ret,_Tp>(__f); } + + template + inline mem_fun1_t<_Ret,_Tp,_Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + + template + inline const_mem_fun1_t<_Ret,_Tp,_Arg> + mem_fun(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_t<_Ret,_Tp,_Arg>(__f); } + + template + inline mem_fun1_ref_t<_Ret,_Tp,_Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) + { return mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + + template + inline const_mem_fun1_ref_t<_Ret,_Tp,_Arg> + mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) + { return const_mem_fun1_ref_t<_Ret,_Tp,_Arg>(__f); } + + /** @} */ + } // namespace std #endif /* _FUNCTION_H */ diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h index 4aa92ffdd20..ce1e1ed00dd 100644 --- a/libstdc++-v3/include/bits/stl_iterator.h +++ b/libstdc++-v3/include/bits/stl_iterator.h @@ -1,6 +1,6 @@ // Iterators -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -137,7 +137,8 @@ namespace std * @return @c current, the %iterator used for underlying work. */ iterator_type - base() const { return current; } + base() const + { return current; } /** * @return TODO @@ -157,7 +158,8 @@ namespace std * @doctodo */ pointer - operator->() const { return &(operator*()); } + operator->() const + { return &(operator*()); } /** * @return TODO @@ -256,7 +258,8 @@ namespace std * @doctodo */ reference - operator[](difference_type __n) const { return *(*this + __n); } + operator[](difference_type __n) const + { return *(*this + __n); } }; //@{ @@ -364,15 +367,18 @@ namespace std /// Simply returns *this. back_insert_iterator& - operator*() { return *this; } + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) back_insert_iterator& - operator++() { return *this; } + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) back_insert_iterator - operator++(int) { return *this; } + operator++(int) + { return *this; } }; /** @@ -435,15 +441,18 @@ namespace std /// Simply returns *this. front_insert_iterator& - operator*() { return *this; } + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) front_insert_iterator& - operator++() { return *this; } + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) front_insert_iterator - operator++(int) { return *this; } + operator++(int) + { return *this; } }; /** @@ -528,15 +537,18 @@ namespace std /// Simply returns *this. insert_iterator& - operator*() { return *this; } + operator*() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) insert_iterator& - operator++() { return *this; } + operator++() + { return *this; } /// Simply returns *this. (This %iterator does not "move".) insert_iterator& - operator++(int) { return *this; } + operator++(int) + { return *this; } }; /** @@ -578,12 +590,12 @@ namespace __gnu_cxx public: typedef typename iterator_traits<_Iterator>::iterator_category - iterator_category; + iterator_category; typedef typename iterator_traits<_Iterator>::value_type value_type; typedef typename iterator_traits<_Iterator>::difference_type - difference_type; - typedef typename iterator_traits<_Iterator>::reference reference; - typedef typename iterator_traits<_Iterator>::pointer pointer; + difference_type; + typedef typename iterator_traits<_Iterator>::reference reference; + typedef typename iterator_traits<_Iterator>::pointer pointer; __normal_iterator() : _M_current(_Iterator()) { } @@ -592,28 +604,41 @@ namespace __gnu_cxx // Allow iterator to const_iterator conversion template - inline __normal_iterator(const __normal_iterator<_Iter, _Container>& __i) + inline __normal_iterator(const __normal_iterator<_Iter, + _Container>& __i) : _M_current(__i.base()) { } // Forward iterator requirements reference - operator*() const { return *_M_current; } + operator*() const + { return *_M_current; } pointer - operator->() const { return _M_current; } + operator->() const + { return _M_current; } __normal_iterator& - operator++() { ++_M_current; return *this; } + operator++() + { + ++_M_current; + return *this; + } __normal_iterator - operator++(int) { return __normal_iterator(_M_current++); } + operator++(int) + { return __normal_iterator(_M_current++); } // Bidirectional iterator requirements __normal_iterator& - operator--() { --_M_current; return *this; } + operator--() + { + --_M_current; + return *this; + } __normal_iterator - operator--(int) { return __normal_iterator(_M_current--); } + operator--(int) + { return __normal_iterator(_M_current--); } // Random access iterator requirements reference @@ -637,7 +662,8 @@ namespace __gnu_cxx { return __normal_iterator(_M_current - __n); } const _Iterator& - base() const { return _M_current; } + base() const + { return _M_current; } }; // Note: In what follows, the left- and right-hand-side iterators are @@ -650,93 +676,93 @@ namespace __gnu_cxx // Forward iterator requirements template - inline bool - operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() == __rhs.base(); } + inline bool + operator==(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } template - inline bool - operator==(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() == __rhs.base(); } + inline bool + operator==(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() == __rhs.base(); } template - inline bool - operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() != __rhs.base(); } + inline bool + operator!=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } template - inline bool - operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() != __rhs.base(); } + inline bool + operator!=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() != __rhs.base(); } // Random access iterator requirements template - inline bool - operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() < __rhs.base(); } + inline bool + operator<(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } template - inline bool - operator<(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() < __rhs.base(); } + inline bool + operator<(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() < __rhs.base(); } template - inline bool - operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() > __rhs.base(); } + inline bool + operator>(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } template - inline bool - operator>(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() > __rhs.base(); } + inline bool + operator>(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() > __rhs.base(); } template - inline bool - operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() <= __rhs.base(); } + inline bool + operator<=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } template - inline bool - operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() <= __rhs.base(); } + inline bool + operator<=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() <= __rhs.base(); } template - inline bool - operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() >= __rhs.base(); } + inline bool + operator>=(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } template - inline bool - operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, - const __normal_iterator<_Iterator, _Container>& __rhs) - { return __lhs.base() >= __rhs.base(); } + inline bool + operator>=(const __normal_iterator<_Iterator, _Container>& __lhs, + const __normal_iterator<_Iterator, _Container>& __rhs) + { return __lhs.base() >= __rhs.base(); } // _GLIBCXX_RESOLVE_LIB_DEFECTS // According to the resolution of DR179 not only the various comparison // operators but also operator- must accept mixed iterator/const_iterator // parameters. template - inline typename __normal_iterator<_IteratorL, _Container>::difference_type - operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, - const __normal_iterator<_IteratorR, _Container>& __rhs) - { return __lhs.base() - __rhs.base(); } + inline typename __normal_iterator<_IteratorL, _Container>::difference_type + operator-(const __normal_iterator<_IteratorL, _Container>& __lhs, + const __normal_iterator<_IteratorR, _Container>& __rhs) + { return __lhs.base() - __rhs.base(); } template - inline __normal_iterator<_Iterator, _Container> - operator+(typename __normal_iterator<_Iterator, _Container>::difference_type __n, - const __normal_iterator<_Iterator, _Container>& __i) - { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } + inline __normal_iterator<_Iterator, _Container> + operator+(typename __normal_iterator<_Iterator, _Container>::difference_type + __n, const __normal_iterator<_Iterator, _Container>& __i) + { return __normal_iterator<_Iterator, _Container>(__i.base() + __n); } } // namespace __gnu_cxx #endif diff --git a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h index a1404e139e4..c933ee0c2be 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_funcs.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_funcs.h @@ -1,6 +1,6 @@ // Functions used by iterators -*- C++ -*- -// Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -78,9 +78,11 @@ namespace std __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) typename iterator_traits<_InputIterator>::difference_type __n = 0; - while (__first != __last) { - ++__first; ++__n; - } + while (__first != __last) + { + ++__first; + ++__n; + } return __n; } @@ -90,7 +92,8 @@ namespace std random_access_iterator_tag) { // concept requirements - __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) return __last - __first; } @@ -111,7 +114,8 @@ namespace std distance(_InputIterator __first, _InputIterator __last) { // concept requirements -- taken care of in __distance - return std::__distance(__first, __last, std::__iterator_category(__first)); + return std::__distance(__first, __last, + std::__iterator_category(__first)); } template @@ -120,7 +124,8 @@ namespace std { // concept requirements __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>) - while (__n--) ++__i; + while (__n--) + ++__i; } template @@ -129,8 +134,8 @@ namespace std bidirectional_iterator_tag) { // concept requirements - __glibcxx_function_requires(_BidirectionalIteratorConcept<_BidirectionalIterator>) - + __glibcxx_function_requires(_BidirectionalIteratorConcept< + _BidirectionalIterator>) if (__n > 0) while (__n--) ++__i; else @@ -143,7 +148,8 @@ namespace std random_access_iterator_tag) { // concept requirements - __glibcxx_function_requires(_RandomAccessIteratorConcept<_RandomAccessIterator>) + __glibcxx_function_requires(_RandomAccessIteratorConcept< + _RandomAccessIterator>) __i += __n; } diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h index 373caba2ca3..5054340e46f 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -1,6 +1,6 @@ // Types used in iterator implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -82,9 +82,11 @@ namespace std struct output_iterator_tag {}; /// Forward iterators support a superset of input iterator operations. struct forward_iterator_tag : public input_iterator_tag {}; - /// Bidirectional iterators support a superset of forward iterator operations. + /// Bidirectional iterators support a superset of forward iterator + /// operations. struct bidirectional_iterator_tag : public forward_iterator_tag {}; - /// Random-access iterators support a superset of bidirectional iterator operations. + /// Random-access iterators support a superset of bidirectional iterator + /// operations. struct random_access_iterator_tag : public bidirectional_iterator_tag {}; //@} diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index fca21e9ed0c..546369b369c 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -94,7 +94,6 @@ namespace __gnu_norm _Tp _M_data; ///< User's data. }; - /** * @brief A list::iterator. * @@ -325,7 +324,6 @@ namespace __gnu_norm } }; - /** * @brief A standard container with linear time access to elements, * and fixed time insertion/deletion at any point in the sequence. @@ -573,7 +571,8 @@ namespace __gnu_norm /// Get a copy of the memory allocation object. allocator_type - get_allocator() const { return _Base::get_allocator(); } + get_allocator() const + { return _Base::get_allocator(); } // iterators /** @@ -581,7 +580,8 @@ namespace __gnu_norm * %list. Iteration is done in ordinary element order. */ iterator - begin() { return this->_M_node._M_next; } + begin() + { return this->_M_node._M_next; } /** * Returns a read-only (constant) iterator that points to the @@ -589,7 +589,8 @@ namespace __gnu_norm * element order. */ const_iterator - begin() const { return this->_M_node._M_next; } + begin() const + { return this->_M_node._M_next; } /** * Returns a read/write iterator that points one past the last @@ -605,7 +606,8 @@ namespace __gnu_norm * element order. */ const_iterator - end() const { return &this->_M_node; } + end() const + { return &this->_M_node; } /** * Returns a read/write reverse iterator that points to the last @@ -613,7 +615,8 @@ namespace __gnu_norm * order. */ reverse_iterator - rbegin() { return reverse_iterator(end()); } + rbegin() + { return reverse_iterator(end()); } /** * Returns a read-only (constant) reverse iterator that points to @@ -621,7 +624,8 @@ namespace __gnu_norm * element order. */ const_reverse_iterator - rbegin() const { return const_reverse_iterator(end()); } + rbegin() const + { return const_reverse_iterator(end()); } /** * Returns a read/write reverse iterator that points to one @@ -629,7 +633,8 @@ namespace __gnu_norm * reverse element order. */ reverse_iterator - rend() { return reverse_iterator(begin()); } + rend() + { return reverse_iterator(begin()); } /** * Returns a read-only (constant) reverse iterator that points to one @@ -646,15 +651,18 @@ namespace __gnu_norm * end().) */ bool - empty() const { return this->_M_node._M_next == &this->_M_node; } + empty() const + { return this->_M_node._M_next == &this->_M_node; } /** Returns the number of elements in the %list. */ size_type - size() const { return std::distance(begin(), end()); } + size() const + { return std::distance(begin(), end()); } /** Returns the size() of the largest possible %list. */ size_type - max_size() const { return size_type(-1); } + max_size() const + { return size_type(-1); } /** * @brief Resizes the %list to the specified number of elements. @@ -679,7 +687,8 @@ namespace __gnu_norm * and new elements are default-constructed. */ void - resize(size_type __new_size) { this->resize(__new_size, value_type()); } + resize(size_type __new_size) + { this->resize(__new_size, value_type()); } // element access /** @@ -687,28 +696,32 @@ namespace __gnu_norm * element of the %list. */ reference - front() { return *begin(); } + front() + { return *begin(); } /** * Returns a read-only (constant) reference to the data at the first * element of the %list. */ const_reference - front() const { return *begin(); } + front() const + { return *begin(); } /** * Returns a read/write reference to the data at the last element * of the %list. */ reference - back() { return *(--end()); } + back() + { return *(--end()); } /** * Returns a read-only (constant) reference to the data at the last * element of the %list. */ const_reference - back() const { return *(--end()); } + back() const + { return *(--end()); } // [23.2.2.3] modifiers /** @@ -722,7 +735,8 @@ namespace __gnu_norm * references. */ void - push_front(const value_type& __x) { this->_M_insert(begin(), __x); } + push_front(const value_type& __x) + { this->_M_insert(begin(), __x); } /** * @brief Removes first element. @@ -737,7 +751,8 @@ namespace __gnu_norm * called. */ void - pop_front() { this->_M_erase(begin()); } + pop_front() + { this->_M_erase(begin()); } /** * @brief Add data to the end of the %list. @@ -750,7 +765,8 @@ namespace __gnu_norm * references. */ void - push_back(const value_type& __x) { this->_M_insert(end(), __x); } + push_back(const value_type& __x) + { this->_M_insert(end(), __x); } /** * @brief Removes last element. @@ -764,7 +780,8 @@ namespace __gnu_norm * is needed, it should be retrieved before pop_back() is called. */ void - pop_back() { this->_M_erase(this->_M_node._M_prev); } + pop_back() + { this->_M_erase(this->_M_node._M_prev); } /** * @brief Inserts given value into %list before specified iterator. @@ -876,7 +893,8 @@ namespace __gnu_norm * function. */ void - swap(list& __x) { _List_node_base::swap(this->_M_node,__x._M_node); } + swap(list& __x) + { _List_node_base::swap(this->_M_node,__x._M_node); } /** * Erases all the elements. Note that this function only erases @@ -922,7 +940,8 @@ namespace __gnu_norm { iterator __j = __i; ++__j; - if (__position == __i || __position == __j) return; + if (__position == __i || __position == __j) + return; this->_M_transfer(__position, __i, __j); } @@ -1037,7 +1056,8 @@ namespace __gnu_norm * Reverse the order of elements in the list in linear time. */ void - reverse() { this->_M_node.reverse(); } + reverse() + { this->_M_node.reverse(); } /** * @brief Sort the elements. @@ -1118,16 +1138,13 @@ namespace __gnu_norm // Moves the elements from [first,last) before position. void _M_transfer(iterator __position, iterator __first, iterator __last) - { - __position._M_node->transfer(__first._M_node,__last._M_node); - } + { __position._M_node->transfer(__first._M_node,__last._M_node); } // Inserts new element at position given and with value given. void _M_insert(iterator __position, const value_type& __x) { _Node* __tmp = _M_create_node(__x); - __tmp->hook(__position._M_node); } @@ -1142,7 +1159,6 @@ namespace __gnu_norm } }; - /** * @brief List equality comparison. * @param x A %list. @@ -1167,7 +1183,7 @@ namespace __gnu_norm { ++__i1; ++__i2; - } + } return __i1 == __end1 && __i2 == __end2; } @@ -1185,10 +1201,8 @@ namespace __gnu_norm template inline bool operator<(const list<_Tp,_Alloc>& __x, const list<_Tp,_Alloc>& __y) - { - return std::lexicographical_compare(__x.begin(), __x.end(), - __y.begin(), __y.end()); - } + { return std::lexicographical_compare(__x.begin(), __x.end(), + __y.begin(), __y.end()); } /// Based on operator== template diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 9895cad0446..e86f4888af9 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -1,6 +1,6 @@ // Map implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -89,503 +89,536 @@ namespace __gnu_norm template , typename _Alloc = allocator > > class map - { - // concept requirements - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) - - public: - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair value_type; - typedef _Compare key_compare; - - class value_compare - : public binary_function - { - friend class map<_Key,_Tp,_Compare,_Alloc>; - protected: - _Compare comp; - value_compare(_Compare __c) : comp(__c) {} - public: - bool operator()(const value_type& __x, const value_type& __y) const - { return comp(__x.first, __y.first); } - }; - - private: - /// @if maint This turns a red-black tree into a [multi]map. @endif - typedef _Rb_tree, key_compare, _Alloc> _Rep_type; - /// @if maint The actual tree structure. @endif - _Rep_type _M_t; - - public: - // many of these are specified differently in ISO, but the following are - // "functionally equivalent" - typedef typename _Rep_type::allocator_type allocator_type; - typedef typename _Rep_type::reference reference; - typedef typename _Rep_type::const_reference const_reference; - typedef typename _Rep_type::iterator iterator; - typedef typename _Rep_type::const_iterator const_iterator; - typedef typename _Rep_type::size_type size_type; - typedef typename _Rep_type::difference_type difference_type; - typedef typename _Rep_type::pointer pointer; - typedef typename _Rep_type::const_pointer const_pointer; - typedef typename _Rep_type::reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - - - // [23.3.1.1] construct/copy/destroy - // (get_allocator() is normally listed in this section, but seems to have - // been accidentally omitted in the printed standard) - /** - * @brief Default constructor creates no elements. - */ - map() : _M_t(_Compare(), allocator_type()) { } - - // for some reason this was made a separate function - /** - * @brief Default constructor creates no elements. - */ - explicit - map(const _Compare& __comp, const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) { } - - /** - * @brief Map copy constructor. - * @param x A %map of identical element and allocator types. - * - * The newly-created %map uses a copy of the allocation object used - * by @a x. - */ - map(const map& __x) - : _M_t(__x._M_t) { } - - /** - * @brief Builds a %map from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %map consisting of copies of the elements from [first,last). - * This is linear in N if the range is already sorted, and NlogN - * otherwise (where N is distance(first,last)). - */ - template - map(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) - { _M_t.insert_unique(__first, __last); } - - /** - * @brief Builds a %map from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param comp A comparison functor. - * @param a An allocator object. - * - * Create a %map consisting of copies of the elements from [first,last). - * This is linear in N if the range is already sorted, and NlogN - * otherwise (where N is distance(first,last)). - */ - template - map(_InputIterator __first, _InputIterator __last, - const _Compare& __comp, const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) - { _M_t.insert_unique(__first, __last); } - - // FIXME There is no dtor declared, but we should have something generated - // by Doxygen. I don't know what tags to add to this paragraph to make - // that happen: - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ - - /** - * @brief Map assignment operator. - * @param x A %map of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - map& - operator=(const map& __x) - { - _M_t = __x._M_t; - return *this; - } - - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _M_t.get_allocator(); } - - // iterators - /** - * Returns a read/write iterator that points to the first pair in the %map. - * Iteration is done in ascending order according to the keys. - */ - iterator - begin() { return _M_t.begin(); } - - /** - * Returns a read-only (constant) iterator that points to the first pair - * in the %map. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - begin() const { return _M_t.begin(); } - - /** - * Returns a read/write iterator that points one past the last pair in the - * %map. Iteration is done in ascending order according to the keys. - */ - iterator - end() { return _M_t.end(); } - - /** - * Returns a read-only (constant) iterator that points one past the last - * pair in the %map. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - end() const { return _M_t.end(); } - - /** - * Returns a read/write reverse iterator that points to the last pair in - * the %map. Iteration is done in descending order according to the keys. - */ - reverse_iterator - rbegin() { return _M_t.rbegin(); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * pair in the %map. Iteration is done in descending order according to - * the keys. - */ - const_reverse_iterator - rbegin() const { return _M_t.rbegin(); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first pair in the %map. Iteration is done in descending order according - * to the keys. - */ - reverse_iterator - rend() { return _M_t.rend(); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first pair in the %map. Iteration is done in descending - * order according to the keys. - */ - const_reverse_iterator - rend() const { return _M_t.rend(); } - - // capacity - /** Returns true if the %map is empty. (Thus begin() would equal end().) */ - bool - empty() const { return _M_t.empty(); } - - /** Returns the size of the %map. */ - size_type - size() const { return _M_t.size(); } - - /** Returns the maximum size of the %map. */ - size_type - max_size() const { return _M_t.max_size(); } - - // [23.3.1.2] element access - /** - * @brief Subscript ( @c [] ) access to %map data. - * @param k The key for which data should be retrieved. - * @return A reference to the data of the (key,data) %pair. - * - * Allows for easy lookup with the subscript ( @c [] ) operator. Returns - * data associated with the key specified in subscript. If the key does - * not exist, a pair with that key is created using default values, which - * is then returned. - * - * Lookup requires logarithmic time. - */ - mapped_type& - operator[](const key_type& __k) { // concept requirements - __glibcxx_function_requires(_DefaultConstructibleConcept) + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) - iterator __i = lower_bound(__k); - // __i->first is greater than or equivalent to __k. - if (__i == end() || key_comp()(__k, (*__i).first)) + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare + : public binary_function + { + friend class map<_Key,_Tp,_Compare,_Alloc>; + protected: + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + + public: + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; + + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + + // [23.3.1.1] construct/copy/destroy + // (get_allocator() is normally listed in this section, but seems to have + // been accidentally omitted in the printed standard) + /** + * @brief Default constructor creates no elements. + */ + map() + : _M_t(_Compare(), allocator_type()) { } + + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + map(const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } + + /** + * @brief Map copy constructor. + * @param x A %map of identical element and allocator types. + * + * The newly-created %map uses a copy of the allocation object used + * by @a x. + */ + map(const map& __x) + : _M_t(__x._M_t) { } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } + + /** + * @brief Builds a %map from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %map consisting of copies of the elements from [first,last). + * This is linear in N if the range is already sorted, and NlogN + * otherwise (where N is distance(first,last)). + */ + template + map(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_unique(__first, __last); } + + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ + + /** + * @brief Map assignment operator. + * @param x A %map of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + map& + operator=(const map& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %map. + * Iteration is done in ascending order according to the keys. + */ + iterator + begin() + { return _M_t.begin(); } + + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %map. Iteration is done in ascending order according to the + * keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %map. Iteration is done in ascending order according to the keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %map. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %map. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %map. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %map. Iteration is done in descending + * order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %map is empty. (Thus begin() would equal + * end().) + */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %map. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %map. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // [23.3.1.2] element access + /** + * @brief Subscript ( @c [] ) access to %map data. + * @param k The key for which data should be retrieved. + * @return A reference to the data of the (key,data) %pair. + * + * Allows for easy lookup with the subscript ( @c [] ) operator. Returns + * data associated with the key specified in subscript. If the key does + * not exist, a pair with that key is created using default values, which + * is then returned. + * + * Lookup requires logarithmic time. + */ + mapped_type& + operator[](const key_type& __k) + { + // concept requirements + __glibcxx_function_requires(_DefaultConstructibleConcept) + + iterator __i = lower_bound(__k); + // __i->first is greater than or equivalent to __k. + if (__i == end() || key_comp()(__k, (*__i).first)) __i = insert(__i, value_type(__k, mapped_type())); - return (*__i).second; - } + return (*__i).second; + } + + // modifiers + /** + * @brief Attempts to insert a std::pair into the %map. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return A pair, of which the first element is an iterator that points + * to the possibly inserted pair, and the second is a bool that + * is true if the pair was actually inserted. + * + * This function attempts to insert a (key, value) %pair into the %map. + * A %map relies on unique keys and thus a %pair is only inserted if its + * first element (the key) is not already present in the %map. + * + * Insertion requires logarithmic time. + */ + pair + insert(const value_type& __x) + { return _M_t.insert_unique(__x); } + + /** + * @brief Attempts to insert a std::pair into the %map. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation of + * pairs). + * @return An iterator that points to the element with key of @a x (may + * or may not be the %pair passed in). + * + * This function is not concerned about whether the insertion took place, + * and thus does not return a boolean like the single-argument + * insert() does. Note that the first parameter is only a hint and can + * potentially improve the performance of the insertion process. A bad + * hint would cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator position, const value_type& __x) + { return _M_t.insert_unique(position, __x); } - // modifiers - /** - * @brief Attempts to insert a std::pair into the %map. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return A pair, of which the first element is an iterator that points - * to the possibly inserted pair, and the second is a bool that - * is true if the pair was actually inserted. - * - * This function attempts to insert a (key, value) %pair into the %map. - * A %map relies on unique keys and thus a %pair is only inserted if its - * first element (the key) is not already present in the %map. - * - * Insertion requires logarithmic time. - */ - pair - insert(const value_type& __x) - { return _M_t.insert_unique(__x); } + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_unique(__first, __last); } - /** - * @brief Attempts to insert a std::pair into the %map. - * @param position An iterator that serves as a hint as to where the - * pair should be inserted. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the element with key of @a x (may - * or may not be the %pair passed in). - * - * This function is not concerned about whether the insertion took place, - * and thus does not return a boolean like the single-argument - * insert() does. Note that the first parameter is only a hint and can - * potentially improve the performance of the insertion process. A bad - * hint would cause no gains in efficiency. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 - * for more on "hinting". - * - * Insertion requires logarithmic time (if the hint is not taken). - */ - iterator - insert(iterator position, const value_type& __x) - { return _M_t.insert_unique(position, __x); } - - /** - * @brief A template function that attemps to insert a range of elements. - * @param first Iterator pointing to the start of the range to be - * inserted. - * @param last Iterator pointing to the end of the range. - * - * Complexity similar to that of the range constructor. - */ - template + /** + * @brief Erases an element from a %map. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %map. Note that this function only erases the element, and + * that if the element is itself a pointer, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_unique(__first, __last); } + erase(iterator __position) + { _M_t.erase(__position); } - /** - * @brief Erases an element from a %map. - * @param position An iterator pointing to the element to be erased. - * - * This function erases an element, pointed to by the given iterator, from - * a %map. Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __position) { _M_t.erase(__position); } + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all the elements located by the given key from + * a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %map. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %map. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %map. + * @param x A %map of the same element and allocator types. + * + * This exchanges the elements between two maps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(map& __x) + { _M_t.swap(__x._M_t); } - /** - * @brief Erases elements according to the provided key. - * @param x Key of element to be erased. - * @return The number of elements erased. - * - * This function erases all the elements located by the given key from - * a %map. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - size_type - erase(const key_type& __x) { return _M_t.erase(__x); } + /** + * Erases all elements in a %map. Note that this function only erases + * the elements, and that if the elements themselves are pointers, the + * pointed-to memory is not touched in any way. Managing the pointer is + * the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } - /** - * @brief Erases a [first,last) range of elements from a %map. - * @param first Iterator pointing to the start of the range to be erased. - * @param last Iterator pointing to the end of the range to be erased. - * - * This function erases a sequence of elements from a %map. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } + // observers + /** + * Returns the key comparison object out of which the %map was + * constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %map was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // [23.3.1.3] map operations + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } - /** - * @brief Swaps data with another %map. - * @param x A %map of the same element and allocator types. - * - * This exchanges the elements between two maps in constant time. - * (It is only swapping a pointer, an integer, and an instance of - * the @c Compare type (which itself is often stateless and empty), so it - * should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(m1,m2) will feed to this function. - */ - void - swap(map& __x) { _M_t.swap(__x._M_t); } + /** + * @brief Tries to locate an element in a %map. + * @param x Key of (key, value) %pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + * + * This function only makes sense for multimaps; for map the result will + * either be 0 (not present) or 1 (present). + */ + size_type + count(const key_type& __x) const + { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } - /** - * Erases all elements in a %map. Note that this function only erases - * the elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void - clear() { _M_t.clear(); } - - // observers - /** - * Returns the key comparison object out of which the %map was constructed. - */ - key_compare - key_comp() const { return _M_t.key_comp(); } - - /** - * Returns a value comparison object, built from the key comparison - * object out of which the %map was constructed. - */ - value_compare - value_comp() const { return value_compare(_M_t.key_comp()); } - - // [23.3.1.3] map operations - /** - * @brief Tries to locate an element in a %map. - * @param x Key of (key, value) %pair to be located. - * @return Iterator pointing to sought-after element, or end() if not - * found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns an iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - iterator - find(const key_type& __x) { return _M_t.find(__x); } - - /** - * @brief Tries to locate an element in a %map. - * @param x Key of (key, value) %pair to be located. - * @return Read-only (constant) iterator pointing to sought-after - * element, or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns a constant iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - const_iterator - find(const key_type& __x) const { return _M_t.find(__x); } - - /** - * @brief Finds the number of elements with given key. - * @param x Key of (key, value) pairs to be located. - * @return Number of elements with specified key. - * - * This function only makes sense for multimaps; for map the result will - * either be 0 (not present) or 1 (present). - */ - size_type - count(const key_type& __x) const - { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to first element equal to or greater - * than key, or end(). - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful it returns an iterator - * pointing to the first element that has a greater value than given key - * or end() if no such element exists. - */ - iterator - lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first element - * equal to or greater than key, or end(). - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful it returns an iterator - * pointing to the first element that has a greater value than given key - * or end() if no such element exists. - */ - const_iterator - lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to the first element - * greater than key, or end(). - */ - iterator - upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first iterator - * greater than key, or end(). - */ - const_iterator - upper_bound(const key_type& __x) const - { return _M_t.upper_bound(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of iterators that possibly points to the subsequence - * matching given key. - * - * This function is equivalent to - * @code - * std::make_pair(c.lower_bound(val), - * c.upper_bound(val)) - * @endcode - * (but is faster than making the calls separately). - * - * This function probably only makes sense for multimaps. - */ - pair - equal_range(const key_type& __x) - { return _M_t.equal_range(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of read-only (constant) iterators that possibly points to - * the subsequence matching given key. - * - * This function is equivalent to - * @code - * std::make_pair(c.lower_bound(val), - * c.upper_bound(val)) - * @endcode - * (but is faster than making the calls separately). - * - * This function probably only makes sense for multimaps. - */ - pair - equal_range(const key_type& __x) const - { return _M_t.equal_range(__x); } - - template - friend bool operator== (const map<_K1,_T1,_C1,_A1>&, - const map<_K1,_T1,_C1,_A1>&); - template - friend bool operator< (const map<_K1,_T1,_C1,_A1>&, - const map<_K1,_T1,_C1,_A1>&); - }; + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multimaps. + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool operator== (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + template + friend bool operator< (const map<_K1,_T1,_C1,_A1>&, + const map<_K1,_T1,_C1,_A1>&); + }; /** * @brief Map equality comparison. diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 4d892283bce..cfd28ef3ad7 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -1,6 +1,6 @@ // Multimap implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -103,466 +103,507 @@ namespace __gnu_norm */ template class multimap - { - // concept requirements - __glibcxx_class_requires(_Tp, _SGIAssignableConcept) - __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) - - public: - typedef _Key key_type; - typedef _Tp mapped_type; - typedef pair value_type; - typedef _Compare key_compare; - - class value_compare + { + // concept requirements + __glibcxx_class_requires(_Tp, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + typedef _Key key_type; + typedef _Tp mapped_type; + typedef pair value_type; + typedef _Compare key_compare; + + class value_compare : public binary_function { - friend class multimap<_Key,_Tp,_Compare,_Alloc>; + friend class multimap<_Key,_Tp,_Compare,_Alloc>; protected: - _Compare comp; - value_compare(_Compare __c) : comp(__c) {} + _Compare comp; + + value_compare(_Compare __c) + : comp(__c) { } + public: - bool operator()(const value_type& __x, const value_type& __y) const - { return comp(__x.first, __y.first); } - }; + bool operator()(const value_type& __x, const value_type& __y) const + { return comp(__x.first, __y.first); } + }; + + private: + /// @if maint This turns a red-black tree into a [multi]map. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; - private: - /// @if maint This turns a red-black tree into a [multi]map. @endif - typedef _Rb_tree, key_compare, _Alloc> _Rep_type; - /// @if maint The actual tree structure. @endif - _Rep_type _M_t; - - public: - // many of these are specified differently in ISO, but the following are - // "functionally equivalent" - typedef typename _Rep_type::allocator_type allocator_type; - typedef typename _Rep_type::reference reference; - typedef typename _Rep_type::const_reference const_reference; - typedef typename _Rep_type::iterator iterator; - typedef typename _Rep_type::const_iterator const_iterator; - typedef typename _Rep_type::size_type size_type; - typedef typename _Rep_type::difference_type difference_type; - typedef typename _Rep_type::pointer pointer; - typedef typename _Rep_type::const_pointer const_pointer; - typedef typename _Rep_type::reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + public: + // many of these are specified differently in ISO, but the following are + // "functionally equivalent" + typedef typename _Rep_type::allocator_type allocator_type; + typedef typename _Rep_type::reference reference; + typedef typename _Rep_type::const_reference const_reference; + typedef typename _Rep_type::iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::pointer pointer; + typedef typename _Rep_type::const_pointer const_pointer; + typedef typename _Rep_type::reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - // [23.3.2] construct/copy/destroy - // (get_allocator() is also listed in this section) - /** - * @brief Default constructor creates no elements. - */ - multimap() : _M_t(_Compare(), allocator_type()) { } + // [23.3.2] construct/copy/destroy + // (get_allocator() is also listed in this section) + /** + * @brief Default constructor creates no elements. + */ + multimap() + : _M_t(_Compare(), allocator_type()) { } - // for some reason this was made a separate function - /** - * @brief Default constructor creates no elements. - */ - explicit - multimap(const _Compare& __comp, const allocator_type& __a = allocator_type()) + // for some reason this was made a separate function + /** + * @brief Default constructor creates no elements. + */ + explicit + multimap(const _Compare& __comp, + const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { } - /** - * @brief %Multimap copy constructor. - * @param x A %multimap of identical element and allocator types. - * - * The newly-created %multimap uses a copy of the allocation object used - * by @a x. - */ - multimap(const multimap& __x) + /** + * @brief %Multimap copy constructor. + * @param x A %multimap of identical element and allocator types. + * + * The newly-created %multimap uses a copy of the allocation object used + * by @a x. + */ + multimap(const multimap& __x) : _M_t(__x._M_t) { } - /** - * @brief Builds a %multimap from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %multimap consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template - multimap(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) { _M_t.insert_equal(__first, __last); } - /** - * @brief Builds a %multimap from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param comp A comparison functor. - * @param a An allocator object. - * - * Create a %multimap consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template - multimap(_InputIterator __first, _InputIterator __last, - const _Compare& __comp, - const allocator_type& __a = allocator_type()) + /** + * @brief Builds a %multimap from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multimap consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multimap(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } - // FIXME There is no dtor declared, but we should have something generated - // by Doxygen. I don't know what tags to add to this paragraph to make - // that happen: - /** - * The dtor only erases the elements, and note that if the elements - * themselves are pointers, the pointed-to memory is not touched in any - * way. Managing the pointer is the user's responsibilty. - */ + // FIXME There is no dtor declared, but we should have something generated + // by Doxygen. I don't know what tags to add to this paragraph to make + // that happen: + /** + * The dtor only erases the elements, and note that if the elements + * themselves are pointers, the pointed-to memory is not touched in any + * way. Managing the pointer is the user's responsibilty. + */ - /** - * @brief %Multimap assignment operator. - * @param x A %multimap of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - multimap& - operator=(const multimap& __x) - { - _M_t = __x._M_t; - return *this; - } + /** + * @brief %Multimap assignment operator. + * @param x A %multimap of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multimap& + operator=(const multimap& __x) + { + _M_t = __x._M_t; + return *this; + } + + /// Get a copy of the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + // iterators + /** + * Returns a read/write iterator that points to the first pair in the + * %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() + { return _M_t.begin(); } - /// Get a copy of the memory allocation object. - allocator_type - get_allocator() const { return _M_t.get_allocator(); } + /** + * Returns a read-only (constant) iterator that points to the first pair + * in the %multimap. Iteration is done in ascending order according to + * the keys. + */ + const_iterator + begin() const + { return _M_t.begin(); } + + /** + * Returns a read/write iterator that points one past the last pair in + * the %multimap. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() + { return _M_t.end(); } + + /** + * Returns a read-only (constant) iterator that points one past the last + * pair in the %multimap. Iteration is done in ascending order according + * to the keys. + */ + const_iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last pair in + * the %multimap. Iteration is done in descending order according to the + * keys. + */ + reverse_iterator + rbegin() + { return _M_t.rbegin(); } + + /** + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + const_reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to one before the + * first pair in the %multimap. Iteration is done in descending order + * according to the keys. + */ + reverse_iterator + rend() + { return _M_t.rend(); } + + /** + * Returns a read-only (constant) reverse iterator that points to one + * before the first pair in the %multimap. Iteration is done in + * descending order according to the keys. + */ + const_reverse_iterator + rend() const + { return _M_t.rend(); } + + // capacity + /** Returns true if the %multimap is empty. */ + bool + empty() const + { return _M_t.empty(); } + + /** Returns the size of the %multimap. */ + size_type + size() const + { return _M_t.size(); } + + /** Returns the maximum size of the %multimap. */ + size_type + max_size() const + { return _M_t.max_size(); } + + // modifiers + /** + * @brief Inserts a std::pair into the %multimap. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } - // iterators - /** - * Returns a read/write iterator that points to the first pair in the - * %multimap. Iteration is done in ascending order according to the keys. - */ - iterator - begin() { return _M_t.begin(); } + /** + * @brief Inserts a std::pair into the %multimap. + * @param position An iterator that serves as a hint as to where the + * pair should be inserted. + * @param x Pair to be inserted (see std::make_pair for easy creation + * of pairs). + * @return An iterator that points to the inserted (key,value) pair. + * + * This function inserts a (key, value) pair into the %multimap. + * Contrary to a std::map the %multimap does not rely on unique keys and + * thus multiple pairs with the same key can be inserted. + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { return _M_t.insert_equal(__position, __x); } + + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } - /** - * Returns a read-only (constant) iterator that points to the first pair - * in the %multimap. Iteration is done in ascending order according to the - * keys. - */ - const_iterator - begin() const { return _M_t.begin(); } - - /** - * Returns a read/write iterator that points one past the last pair in the - * %multimap. Iteration is done in ascending order according to the keys. - */ - iterator - end() { return _M_t.end(); } - - /** - * Returns a read-only (constant) iterator that points one past the last - * pair in the %multimap. Iteration is done in ascending order according - * to the keys. - */ - const_iterator - end() const { return _M_t.end(); } - - /** - * Returns a read/write reverse iterator that points to the last pair in - * the %multimap. Iteration is done in descending order according to the - * keys. - */ - reverse_iterator - rbegin() { return _M_t.rbegin(); } - - /** - * Returns a read-only (constant) reverse iterator that points to the last - * pair in the %multimap. Iteration is done in descending order according - * to the keys. - */ - const_reverse_iterator - rbegin() const { return _M_t.rbegin(); } - - /** - * Returns a read/write reverse iterator that points to one before the - * first pair in the %multimap. Iteration is done in descending order - * according to the keys. - */ - reverse_iterator - rend() { return _M_t.rend(); } - - /** - * Returns a read-only (constant) reverse iterator that points to one - * before the first pair in the %multimap. Iteration is done in descending - * order according to the keys. - */ - const_reverse_iterator - rend() const { return _M_t.rend(); } - - // capacity - /** Returns true if the %multimap is empty. */ - bool - empty() const { return _M_t.empty(); } - - /** Returns the size of the %multimap. */ - size_type - size() const { return _M_t.size(); } - - /** Returns the maximum size of the %multimap. */ - size_type - max_size() const { return _M_t.max_size(); } - - // modifiers - /** - * @brief Inserts a std::pair into the %multimap. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the inserted (key,value) pair. - * - * This function inserts a (key, value) pair into the %multimap. Contrary - * to a std::map the %multimap does not rely on unique keys and thus - * multiple pairs with the same key can be inserted. - * - * Insertion requires logarithmic time. - */ - iterator - insert(const value_type& __x) { return _M_t.insert_equal(__x); } - - /** - * @brief Inserts a std::pair into the %multimap. - * @param position An iterator that serves as a hint as to where the - * pair should be inserted. - * @param x Pair to be inserted (see std::make_pair for easy creation of - * pairs). - * @return An iterator that points to the inserted (key,value) pair. - * - * This function inserts a (key, value) pair into the %multimap. Contrary - * to a std::map the %multimap does not rely on unique keys and thus - * multiple pairs with the same key can be inserted. - * Note that the first parameter is only a hint and can potentially - * improve the performance of the insertion process. A bad hint would - * cause no gains in efficiency. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 - * for more on "hinting". - * - * Insertion requires logarithmic time (if the hint is not taken). - */ - iterator - insert(iterator __position, const value_type& __x) - { return _M_t.insert_equal(__position, __x); } - - /** - * @brief A template function that attemps to insert a range of elements. - * @param first Iterator pointing to the start of the range to be - * inserted. - * @param last Iterator pointing to the end of the range. - * - * Complexity similar to that of the range constructor. - */ - template + /** + * @brief Erases an element from a %multimap. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multimap. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ void - insert(_InputIterator __first, _InputIterator __last) - { _M_t.insert_equal(__first, __last); } + erase(iterator __position) + { _M_t.erase(__position); } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multimap. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } - /** - * @brief Erases an element from a %multimap. - * @param position An iterator pointing to the element to be erased. - * - * This function erases an element, pointed to by the given iterator, from - * a %multimap. Note that this function only erases the element, and that - * if the element is itself a pointer, the pointed-to memory is not - * touched in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __position) { _M_t.erase(__position); } + /** + * @brief Erases a [first,last) range of elements from a %multimap. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multimap. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { _M_t.erase(__first, __last); } + + /** + * @brief Swaps data with another %multimap. + * @param x A %multimap of the same element and allocator types. + * + * This exchanges the elements between two multimaps in constant time. + * (It is only swapping a pointer, an integer, and an instance of + * the @c Compare type (which itself is often stateless and empty), so it + * should be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(m1,m2) will feed to this function. + */ + void + swap(multimap& __x) + { _M_t.swap(__x._M_t); } + + /** + * Erases all elements in a %multimap. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // observers + /** + * Returns the key comparison object out of which the %multimap + * was constructed. + */ + key_compare + key_comp() const + { return _M_t.key_comp(); } + + /** + * Returns a value comparison object, built from the key comparison + * object out of which the %multimap was constructed. + */ + value_compare + value_comp() const + { return value_compare(_M_t.key_comp()); } + + // multimap operations + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to sought-after element, + * or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after %pair. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + /** + * @brief Tries to locate an element in a %multimap. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to sought-after + * element, or end() if not found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns a constant + * iterator pointing to the sought after %pair. If unsuccessful it + * returns the past-the-end ( @c end() ) iterator. + */ + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + + /** + * @brief Finds the number of elements with given key. + * @param x Key of (key, value) pairs to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } - /** - * @brief Erases elements according to the provided key. - * @param x Key of element to be erased. - * @return The number of elements erased. - * - * This function erases all elements located by the given key from a - * %multimap. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - size_type - erase(const key_type& __x) { return _M_t.erase(__x); } + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first element + * equal to or greater than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful the iterator will point + * to the next greatest element or, if no such greater element exists, to + * end(). + */ + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key of (key, value) pair to be located. + * @return Read-only (constant) iterator pointing to first iterator + * greater than key, or end(). + */ + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } - /** - * @brief Erases a [first,last) range of elements from a %multimap. - * @param first Iterator pointing to the start of the range to be erased. - * @param last Iterator pointing to the end of the range to be erased. - * - * This function erases a sequence of elements from a %multimap. - * Note that this function only erases the elements, and that if - * the elements themselves are pointers, the pointed-to memory is not - * touched in any way. Managing the pointer is the user's responsibilty. - */ - void - erase(iterator __first, iterator __last) { _M_t.erase(__first, __last); } + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } - /** - * @brief Swaps data with another %multimap. - * @param x A %multimap of the same element and allocator types. - * - * This exchanges the elements between two multimaps in constant time. - * (It is only swapping a pointer, an integer, and an instance of - * the @c Compare type (which itself is often stateless and empty), so it - * should be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(m1,m2) will feed to this function. - */ - void - swap(multimap& __x) { _M_t.swap(__x._M_t); } + /** + * @brief Finds a subsequence matching given key. + * @param x Key of (key, value) pairs to be located. + * @return Pair of read-only (constant) iterators that possibly points + * to the subsequence matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + */ + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } - /** - * Erases all elements in a %multimap. Note that this function only erases - * the elements, and that if the elements themselves are pointers, the - * pointed-to memory is not touched in any way. Managing the pointer is - * the user's responsibilty. - */ - void - clear() { _M_t.clear(); } - - // observers - /** - * Returns the key comparison object out of which the %multimap - * was constructed. - */ - key_compare - key_comp() const { return _M_t.key_comp(); } - - /** - * Returns a value comparison object, built from the key comparison - * object out of which the %multimap was constructed. - */ - value_compare - value_comp() const { return value_compare(_M_t.key_comp()); } - - // multimap operations - /** - * @brief Tries to locate an element in a %multimap. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to sought-after element, - * or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns an iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - iterator - find(const key_type& __x) { return _M_t.find(__x); } - - /** - * @brief Tries to locate an element in a %multimap. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to sought-after - * element, or end() if not found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns a constant iterator - * pointing to the sought after %pair. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - const_iterator - find(const key_type& __x) const { return _M_t.find(__x); } - - /** - * @brief Finds the number of elements with given key. - * @param x Key of (key, value) pairs to be located. - * @return Number of elements with specified key. - */ - size_type - count(const key_type& __x) const { return _M_t.count(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to first element equal to or greater - * than key, or end(). - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful it returns an iterator - * pointing to the first element that has a greater value than given key - * or end() if no such element exists. - */ - iterator - lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first element - * equal to or greater than key, or end(). - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful the iterator will point - * to the next greatest element or, if no such greater element exists, to - * end(). - */ - const_iterator - lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Iterator pointing to the first element - * greater than key, or end(). - */ - iterator - upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } - - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key of (key, value) pair to be located. - * @return Read-only (constant) iterator pointing to first iterator - * greater than key, or end(). - */ - const_iterator - upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of iterators that possibly points to the subsequence - * matching given key. - * - * This function is equivalent to - * @code - * std::make_pair(c.lower_bound(val), - * c.upper_bound(val)) - * @endcode - * (but is faster than making the calls separately). - */ - pair - equal_range(const key_type& __x) { return _M_t.equal_range(__x); } - - /** - * @brief Finds a subsequence matching given key. - * @param x Key of (key, value) pairs to be located. - * @return Pair of read-only (constant) iterators that possibly points to - * the subsequence matching given key. - * - * This function is equivalent to - * @code - * std::make_pair(c.lower_bound(val), - * c.upper_bound(val)) - * @endcode - * (but is faster than making the calls separately). - */ - pair - equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } - - template - friend bool operator== (const multimap<_K1,_T1,_C1,_A1>&, - const multimap<_K1,_T1,_C1,_A1>&); - template - friend bool operator< (const multimap<_K1,_T1,_C1,_A1>&, - const multimap<_K1,_T1,_C1,_A1>&); + template + friend bool + operator== (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); + + template + friend bool + operator< (const multimap<_K1,_T1,_C1,_A1>&, + const multimap<_K1,_T1,_C1,_A1>&); }; - - + /** * @brief Multimap equality comparison. * @param x A %multimap. @@ -577,9 +618,7 @@ namespace __gnu_norm inline bool operator==(const multimap<_Key,_Tp,_Compare,_Alloc>& __x, const multimap<_Key,_Tp,_Compare,_Alloc>& __y) - { - return __x._M_t == __y._M_t; - } + { return __x._M_t == __y._M_t; } /** * @brief Multimap ordering relation. diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 2cd26d072e8..c72d9938ddc 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -66,19 +66,18 @@ namespace __gnu_norm { -// Forward declaration of operators < and ==, needed for friend declaration. + // Forward declaration of operators < and ==, needed for friend declaration. + template , + class _Alloc = allocator<_Key> > + class multiset; -template , - class _Alloc = allocator<_Key> > -class multiset; + template + inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); -template -inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y); - -template -inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, - const multiset<_Key,_Compare,_Alloc>& __y); + template + inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, + const multiset<_Key,_Compare,_Alloc>& __y); /** * @brief A standard container made up of elements, which can be retrieved @@ -101,362 +100,410 @@ inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, * @endif */ template - class multiset - { - // concept requirements - __glibcxx_class_requires(_Key, _SGIAssignableConcept) - __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) + class multiset + { + // concept requirements + __glibcxx_class_requires(_Key, _SGIAssignableConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) + + public: + // typedefs: + typedef _Key key_type; + typedef _Key value_type; + typedef _Compare key_compare; + typedef _Compare value_compare; + + private: + /// @if maint This turns a red-black tree into a [multi]set. @endif + typedef _Rb_tree, key_compare, _Alloc> _Rep_type; + /// @if maint The actual tree structure. @endif + _Rep_type _M_t; - public: - - // typedefs: - - typedef _Key key_type; - typedef _Key value_type; - typedef _Compare key_compare; - typedef _Compare value_compare; - - private: - /// @if maint This turns a red-black tree into a [multi]set. @endif - typedef _Rb_tree, key_compare, _Alloc> _Rep_type; - /// @if maint The actual tree structure. @endif - _Rep_type _M_t; - - public: - typedef typename _Alloc::pointer pointer; - typedef typename _Alloc::const_pointer const_pointer; - typedef typename _Alloc::reference reference; - typedef typename _Alloc::const_reference const_reference; - typedef typename _Rep_type::const_iterator iterator; - typedef typename _Rep_type::const_iterator const_iterator; - typedef typename _Rep_type::const_reverse_iterator reverse_iterator; - typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; - typedef typename _Rep_type::size_type size_type; - typedef typename _Rep_type::difference_type difference_type; - typedef typename _Rep_type::allocator_type allocator_type; + public: + typedef typename _Alloc::pointer pointer; + typedef typename _Alloc::const_pointer const_pointer; + typedef typename _Alloc::reference reference; + typedef typename _Alloc::const_reference const_reference; + typedef typename _Rep_type::const_iterator iterator; + typedef typename _Rep_type::const_iterator const_iterator; + typedef typename _Rep_type::const_reverse_iterator reverse_iterator; + typedef typename _Rep_type::const_reverse_iterator const_reverse_iterator; + typedef typename _Rep_type::size_type size_type; + typedef typename _Rep_type::difference_type difference_type; + typedef typename _Rep_type::allocator_type allocator_type; // allocation/deallocation - + /** * @brief Default constructor creates no elements. - */ - multiset() : _M_t(_Compare(), allocator_type()) {} - explicit multiset(const _Compare& __comp, - const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) {} - - /** - * @brief Builds a %multiset from a range. - * @param first An input iterator. - * @param last An input iterator. - * - * Create a %multiset consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template - multiset(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) - { _M_t.insert_equal(__first, __last); } - - /** - * @brief Builds a %multiset from a range. - * @param first An input iterator. - * @param last An input iterator. - * @param comp A comparison functor. - * @param a An allocator object. - * - * Create a %multiset consisting of copies of the elements from - * [first,last). This is linear in N if the range is already sorted, - * and NlogN otherwise (where N is distance(first,last)). - */ - template - multiset(_InputIterator __first, _InputIterator __last, - const _Compare& __comp, - const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) { _M_t.insert_equal(__first, __last); } - - /** - * @brief %Multiset copy constructor. - * @param x A %multiset of identical element and allocator types. - * - * The newly-created %multiset uses a copy of the allocation object used - * by @a x. - */ - multiset(const multiset<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} - - /** - * @brief %Multiset assignment operator. - * @param x A %multiset of identical element and allocator types. - * - * All the elements of @a x are copied, but unlike the copy constructor, - * the allocator object is not copied. - */ - multiset<_Key,_Compare,_Alloc>& - operator=(const multiset<_Key,_Compare,_Alloc>& __x) { - _M_t = __x._M_t; - return *this; - } - - // accessors: - - /// Returns the comparison object. - key_compare key_comp() const { return _M_t.key_comp(); } - /// Returns the comparison object. - value_compare value_comp() const { return _M_t.key_comp(); } - /// Returns the memory allocation object. - allocator_type get_allocator() const { return _M_t.get_allocator(); } - - /** - * Returns a read/write iterator that points to the first element in the - * %multiset. Iteration is done in ascending order according to the - * keys. */ - iterator begin() const { return _M_t.begin(); } + multiset() + : _M_t(_Compare(), allocator_type()) { } - /** - * Returns a read/write iterator that points one past the last element in - * the %multiset. Iteration is done in ascending order according to the - * keys. - */ - iterator end() const { return _M_t.end(); } + explicit multiset(const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) { } - /** - * Returns a read/write reverse iterator that points to the last element - * in the %multiset. Iteration is done in descending order according to - * the keys. - */ - reverse_iterator rbegin() const { return _M_t.rbegin(); } - - /** - * Returns a read/write reverse iterator that points to the last element - * in the %multiset. Iteration is done in descending order according to - * the keys. - */ - reverse_iterator rend() const { return _M_t.rend(); } + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_equal(__first, __last); } - /// Returns true if the %set is empty. - bool empty() const { return _M_t.empty(); } + /** + * @brief Builds a %multiset from a range. + * @param first An input iterator. + * @param last An input iterator. + * @param comp A comparison functor. + * @param a An allocator object. + * + * Create a %multiset consisting of copies of the elements from + * [first,last). This is linear in N if the range is already sorted, + * and NlogN otherwise (where N is distance(first,last)). + */ + template + multiset(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) + : _M_t(__comp, __a) + { _M_t.insert_equal(__first, __last); } - /// Returns the size of the %set. - size_type size() const { return _M_t.size(); } + /** + * @brief %Multiset copy constructor. + * @param x A %multiset of identical element and allocator types. + * + * The newly-created %multiset uses a copy of the allocation object used + * by @a x. + */ + multiset(const multiset<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } - /// Returns the maximum size of the %set. - size_type max_size() const { return _M_t.max_size(); } + /** + * @brief %Multiset assignment operator. + * @param x A %multiset of identical element and allocator types. + * + * All the elements of @a x are copied, but unlike the copy constructor, + * the allocator object is not copied. + */ + multiset<_Key,_Compare,_Alloc>& + operator=(const multiset<_Key,_Compare,_Alloc>& __x) + { + _M_t = __x._M_t; + return *this; + } + + // accessors: + + /// Returns the comparison object. + key_compare + key_comp() const + { return _M_t.key_comp(); } + /// Returns the comparison object. + value_compare + value_comp() const + { return _M_t.key_comp(); } + /// Returns the memory allocation object. + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } + + /** + * Returns a read/write iterator that points to the first element in the + * %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + begin() const + { return _M_t.begin(); } - /** - * @brief Swaps data with another %multiset. - * @param x A %multiset of the same element and allocator types. - * - * This exchanges the elements between two multisets in constant time. - * (It is only swapping a pointer, an integer, and an instance of the @c - * Compare type (which itself is often stateless and empty), so it should - * be quite fast.) - * Note that the global std::swap() function is specialized such that - * std::swap(s1,s2) will feed to this function. - */ - void swap(multiset<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + /** + * Returns a read/write iterator that points one past the last element in + * the %multiset. Iteration is done in ascending order according to the + * keys. + */ + iterator + end() const + { return _M_t.end(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } + + /** + * Returns a read/write reverse iterator that points to the last element + * in the %multiset. Iteration is done in descending order according to + * the keys. + */ + reverse_iterator + rend() const + { return _M_t.rend(); } + + /// Returns true if the %set is empty. + bool + empty() const + { return _M_t.empty(); } + + /// Returns the size of the %set. + size_type + size() const + { return _M_t.size(); } + + /// Returns the maximum size of the %set. + size_type + max_size() const + { return _M_t.max_size(); } + + /** + * @brief Swaps data with another %multiset. + * @param x A %multiset of the same element and allocator types. + * + * This exchanges the elements between two multisets in constant time. + * (It is only swapping a pointer, an integer, and an instance of the @c + * Compare type (which itself is often stateless and empty), so it should + * be quite fast.) + * Note that the global std::swap() function is specialized such that + * std::swap(s1,s2) will feed to this function. + */ + void + swap(multiset<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } + + // insert/erase + /** + * @brief Inserts an element into the %multiset. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Insertion requires logarithmic time. + */ + iterator + insert(const value_type& __x) + { return _M_t.insert_equal(__x); } + + /** + * @brief Inserts an element into the %multiset. + * @param position An iterator that serves as a hint as to where the + * element should be inserted. + * @param x Element to be inserted. + * @return An iterator that points to the inserted element. + * + * This function inserts an element into the %multiset. Contrary + * to a std::set the %multiset does not rely on unique keys and thus + * multiple copies of the same element can be inserted. + * + * Note that the first parameter is only a hint and can potentially + * improve the performance of the insertion process. A bad hint would + * cause no gains in efficiency. + * + * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 + * for more on "hinting". + * + * Insertion requires logarithmic time (if the hint is not taken). + */ + iterator + insert(iterator __position, const value_type& __x) + { + typedef typename _Rep_type::iterator _Rep_iterator; + return _M_t.insert_equal((_Rep_iterator&)__position, __x); + } - // insert/erase - /** - * @brief Inserts an element into the %multiset. - * @param x Element to be inserted. - * @return An iterator that points to the inserted element. - * - * This function inserts an element into the %multiset. Contrary - * to a std::set the %multiset does not rely on unique keys and thus - * multiple copies of the same element can be inserted. - * - * Insertion requires logarithmic time. - */ - iterator insert(const value_type& __x) { - return _M_t.insert_equal(__x); - } + /** + * @brief A template function that attemps to insert a range of elements. + * @param first Iterator pointing to the start of the range to be + * inserted. + * @param last Iterator pointing to the end of the range. + * + * Complexity similar to that of the range constructor. + */ + template + void + insert(_InputIterator __first, _InputIterator __last) + { _M_t.insert_equal(__first, __last); } - /** - * @brief Inserts an element into the %multiset. - * @param position An iterator that serves as a hint as to where the - * element should be inserted. - * @param x Element to be inserted. - * @return An iterator that points to the inserted element. - * - * This function inserts an element into the %multiset. Contrary - * to a std::set the %multiset does not rely on unique keys and thus - * multiple copies of the same element can be inserted. - * - * Note that the first parameter is only a hint and can potentially - * improve the performance of the insertion process. A bad hint would - * cause no gains in efficiency. - * - * See http://gcc.gnu.org/onlinedocs/libstdc++/23_containers/howto.html#4 - * for more on "hinting". - * - * Insertion requires logarithmic time (if the hint is not taken). - */ - iterator insert(iterator __position, const value_type& __x) { - typedef typename _Rep_type::iterator _Rep_iterator; - return _M_t.insert_equal((_Rep_iterator&)__position, __x); - } + /** + * @brief Erases an element from a %multiset. + * @param position An iterator pointing to the element to be erased. + * + * This function erases an element, pointed to by the given iterator, + * from a %multiset. Note that this function only erases the element, + * and that if the element is itself a pointer, the pointed-to memory is + * not touched in any way. Managing the pointer is the user's + * responsibilty. + */ + void + erase(iterator __position) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__position); + } + + /** + * @brief Erases elements according to the provided key. + * @param x Key of element to be erased. + * @return The number of elements erased. + * + * This function erases all elements located by the given key from a + * %multiset. + * Note that this function only erases the element, and that if + * the element is itself a pointer, the pointed-to memory is not touched + * in any way. Managing the pointer is the user's responsibilty. + */ + size_type + erase(const key_type& __x) + { return _M_t.erase(__x); } + + /** + * @brief Erases a [first,last) range of elements from a %multiset. + * @param first Iterator pointing to the start of the range to be + * erased. + * @param last Iterator pointing to the end of the range to be erased. + * + * This function erases a sequence of elements from a %multiset. + * Note that this function only erases the elements, and that if + * the elements themselves are pointers, the pointed-to memory is not + * touched in any way. Managing the pointer is the user's responsibilty. + */ + void + erase(iterator __first, iterator __last) + { + typedef typename _Rep_type::iterator _Rep_iterator; + _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); + } + + /** + * Erases all elements in a %multiset. Note that this function only + * erases the elements, and that if the elements themselves are pointers, + * the pointed-to memory is not touched in any way. Managing the pointer + * is the user's responsibilty. + */ + void + clear() + { _M_t.clear(); } + + // multiset operations: + + /** + * @brief Finds the number of elements with given key. + * @param x Key of elements to be located. + * @return Number of elements with specified key. + */ + size_type + count(const key_type& __x) const + { return _M_t.count(__x); } + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 214. set::find() missing const overload + //@{ + /** + * @brief Tries to locate an element in a %set. + * @param x Element to be located. + * @return Iterator pointing to sought-after element, or end() if not + * found. + * + * This function takes a key and tries to locate the element with which + * the key matches. If successful the function returns an iterator + * pointing to the sought after element. If unsuccessful it returns the + * past-the-end ( @c end() ) iterator. + */ + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } + //@} + + //@{ + /** + * @brief Finds the beginning of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to first element equal to or greater + * than key, or end(). + * + * This function returns the first element of a subsequence of elements + * that matches the given key. If unsuccessful it returns an iterator + * pointing to the first element that has a greater value than given key + * or end() if no such element exists. + */ + iterator + lower_bound(const key_type& __x) + { return _M_t.lower_bound(__x); } + + const_iterator + lower_bound(const key_type& __x) const + { return _M_t.lower_bound(__x); } + //@} + + //@{ + /** + * @brief Finds the end of a subsequence matching given key. + * @param x Key to be located. + * @return Iterator pointing to the first element + * greater than key, or end(). + */ + iterator + upper_bound(const key_type& __x) + { return _M_t.upper_bound(__x); } + + const_iterator + upper_bound(const key_type& __x) const + { return _M_t.upper_bound(__x); } + //@} + + //@{ + /** + * @brief Finds a subsequence matching given key. + * @param x Key to be located. + * @return Pair of iterators that possibly points to the subsequence + * matching given key. + * + * This function is equivalent to + * @code + * std::make_pair(c.lower_bound(val), + * c.upper_bound(val)) + * @endcode + * (but is faster than making the calls separately). + * + * This function probably only makes sense for multisets. + */ + pair + equal_range(const key_type& __x) + { return _M_t.equal_range(__x); } + + pair + equal_range(const key_type& __x) const + { return _M_t.equal_range(__x); } + + template + friend bool + operator== (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); - /** - * @brief A template function that attemps to insert a range of elements. - * @param first Iterator pointing to the start of the range to be - * inserted. - * @param last Iterator pointing to the end of the range. - * - * Complexity similar to that of the range constructor. - */ - template - void insert(_InputIterator __first, _InputIterator __last) { - _M_t.insert_equal(__first, __last); - } - - /** - * @brief Erases an element from a %multiset. - * @param position An iterator pointing to the element to be erased. - * - * This function erases an element, pointed to by the given iterator, - * from a %multiset. Note that this function only erases the element, - * and that if the element is itself a pointer, the pointed-to memory is - * not touched in any way. Managing the pointer is the user's - * responsibilty. - */ - void erase(iterator __position) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__position); - } - - /** - * @brief Erases elements according to the provided key. - * @param x Key of element to be erased. - * @return The number of elements erased. - * - * This function erases all elements located by the given key from a - * %multiset. - * Note that this function only erases the element, and that if - * the element is itself a pointer, the pointed-to memory is not touched - * in any way. Managing the pointer is the user's responsibilty. - */ - size_type erase(const key_type& __x) { - return _M_t.erase(__x); - } - - /** - * @brief Erases a [first,last) range of elements from a %multiset. - * @param first Iterator pointing to the start of the range to be erased. - * @param last Iterator pointing to the end of the range to be erased. - * - * This function erases a sequence of elements from a %multiset. - * Note that this function only erases the elements, and that if - * the elements themselves are pointers, the pointed-to memory is not - * touched in any way. Managing the pointer is the user's responsibilty. - */ - void erase(iterator __first, iterator __last) { - typedef typename _Rep_type::iterator _Rep_iterator; - _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); - } - - /** - * Erases all elements in a %multiset. Note that this function only - * erases the elements, and that if the elements themselves are pointers, - * the pointed-to memory is not touched in any way. Managing the pointer - * is the user's responsibilty. - */ - void clear() { _M_t.clear(); } - - // multiset operations: - - /** - * @brief Finds the number of elements with given key. - * @param x Key of elements to be located. - * @return Number of elements with specified key. - */ - size_type count(const key_type& __x) const { return _M_t.count(__x); } - - // _GLIBCXX_RESOLVE_LIB_DEFECTS - // 214. set::find() missing const overload - //@{ - /** - * @brief Tries to locate an element in a %set. - * @param x Element to be located. - * @return Iterator pointing to sought-after element, or end() if not - * found. - * - * This function takes a key and tries to locate the element with which - * the key matches. If successful the function returns an iterator - * pointing to the sought after element. If unsuccessful it returns the - * past-the-end ( @c end() ) iterator. - */ - iterator find(const key_type& __x) { return _M_t.find(__x); } - const_iterator find(const key_type& __x) const { return _M_t.find(__x); } - //@} - - //@{ - /** - * @brief Finds the beginning of a subsequence matching given key. - * @param x Key to be located. - * @return Iterator pointing to first element equal to or greater - * than key, or end(). - * - * This function returns the first element of a subsequence of elements - * that matches the given key. If unsuccessful it returns an iterator - * pointing to the first element that has a greater value than given key - * or end() if no such element exists. - */ - iterator lower_bound(const key_type& __x) { - return _M_t.lower_bound(__x); - } - const_iterator lower_bound(const key_type& __x) const { - return _M_t.lower_bound(__x); - } - //@} - - //@{ - /** - * @brief Finds the end of a subsequence matching given key. - * @param x Key to be located. - * @return Iterator pointing to the first element - * greater than key, or end(). - */ - iterator upper_bound(const key_type& __x) { - return _M_t.upper_bound(__x); - } - const_iterator upper_bound(const key_type& __x) const { - return _M_t.upper_bound(__x); - } - //@} - - //@{ - /** - * @brief Finds a subsequence matching given key. - * @param x Key to be located. - * @return Pair of iterators that possibly points to the subsequence - * matching given key. - * - * This function is equivalent to - * @code - * std::make_pair(c.lower_bound(val), - * c.upper_bound(val)) - * @endcode - * (but is faster than making the calls separately). - * - * This function probably only makes sense for multisets. - */ - pair equal_range(const key_type& __x) { - return _M_t.equal_range(__x); - } - pair equal_range(const key_type& __x) const { - return _M_t.equal_range(__x); - } - - template - friend bool operator== (const multiset<_K1,_C1,_A1>&, - const multiset<_K1,_C1,_A1>&); - template - friend bool operator< (const multiset<_K1,_C1,_A1>&, - const multiset<_K1,_C1,_A1>&); - }; + template + friend bool + operator< (const multiset<_K1,_C1,_A1>&, + const multiset<_K1,_C1,_A1>&); + }; /** * @brief Multiset equality comparison. @@ -464,7 +511,8 @@ inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, * @param y A %multiset of the same type as @a x. * @return True iff the size and elements of the multisets are equal. * - * This is an equivalence relation. It is linear in the size of the multisets. + * This is an equivalence relation. It is linear in the size of the + * multisets. * Multisets are considered equivalent if their sizes are equal, and if * corresponding elements compare equal. */ @@ -472,8 +520,8 @@ inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, inline bool operator==(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return __x._M_t == __y._M_t; } - + { return __x._M_t == __y._M_t; } + /** * @brief Multiset ordering relation. * @param x A %multiset. @@ -489,42 +537,42 @@ inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, inline bool operator<(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return __x._M_t < __y._M_t; } + { return __x._M_t < __y._M_t; } /// Returns !(x == y). template inline bool operator!=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return !(__x == __y); } + { return !(__x == __y); } /// Returns y < x. template inline bool operator>(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return __y < __x; } + { return __y < __x; } /// Returns !(y < x) template inline bool operator<=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return !(__y < __x); } + { return !(__y < __x); } /// Returns !(x < y) template inline bool operator>=(const multiset<_Key,_Compare,_Alloc>& __x, const multiset<_Key,_Compare,_Alloc>& __y) - { return !(__x < __y); } + { return !(__x < __y); } /// See std::multiset::swap(). template inline void swap(multiset<_Key,_Compare,_Alloc>& __x, multiset<_Key,_Compare,_Alloc>& __y) - { __x.swap(__y); } + { __x.swap(__y); } } // namespace __gnu_norm diff --git a/libstdc++-v3/include/bits/stl_relops.h b/libstdc++-v3/include/bits/stl_relops.h index 18561ec2dc1..812679ccd6e 100644 --- a/libstdc++-v3/include/bits/stl_relops.h +++ b/libstdc++-v3/include/bits/stl_relops.h @@ -1,6 +1,6 @@ // std::rel_ops implementation -*- C++ -*- -// Copyright (C) 2001, 2002 Free Software Foundation, Inc. +// Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -75,61 +75,61 @@ namespace std { namespace rel_ops { - /** @namespace std::rel_ops - * @brief The generated relational operators are sequestered here. - */ + /** @namespace std::rel_ops + * @brief The generated relational operators are sequestered here. + */ + + /** + * @brief Defines @c != for arbitrary types, in terms of @c ==. + * @param x A thing. + * @param y Another thing. + * @return x != y + * + * This function uses @c == to determine its result. + */ + template + inline bool + operator!=(const _Tp& __x, const _Tp& __y) + { return !(__x == __y); } -/** - * @brief Defines @c != for arbitrary types, in terms of @c ==. - * @param x A thing. - * @param y Another thing. - * @return x != y - * - * This function uses @c == to determine its result. -*/ -template -inline bool operator!=(const _Tp& __x, const _Tp& __y) { - return !(__x == __y); -} + /** + * @brief Defines @c > for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x > y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>(const _Tp& __x, const _Tp& __y) + { return __y < __x; } -/** - * @brief Defines @c > for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x > y - * - * This function uses @c < to determine its result. -*/ -template -inline bool operator>(const _Tp& __x, const _Tp& __y) { - return __y < __x; -} + /** + * @brief Defines @c <= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x <= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator<=(const _Tp& __x, const _Tp& __y) + { return !(__y < __x); } -/** - * @brief Defines @c <= for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x <= y - * - * This function uses @c < to determine its result. -*/ -template -inline bool operator<=(const _Tp& __x, const _Tp& __y) { - return !(__y < __x); -} - -/** - * @brief Defines @c >= for arbitrary types, in terms of @c <. - * @param x A thing. - * @param y Another thing. - * @return x >= y - * - * This function uses @c < to determine its result. -*/ -template -inline bool operator>=(const _Tp& __x, const _Tp& __y) { - return !(__x < __y); -} + /** + * @brief Defines @c >= for arbitrary types, in terms of @c <. + * @param x A thing. + * @param y Another thing. + * @return x >= y + * + * This function uses @c < to determine its result. + */ + template + inline bool + operator>=(const _Tp& __x, const _Tp& __y) + { return !(__x < __y); } } // namespace rel_ops } // namespace std diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index a3f5472df7c..1e45f99df67 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -108,7 +108,8 @@ namespace __gnu_norm { // concept requirements __glibcxx_class_requires(_Key, _SGIAssignableConcept) - __glibcxx_class_requires4(_Compare, bool, _Key, _Key, _BinaryFunctionConcept) + __glibcxx_class_requires4(_Compare, bool, _Key, _Key, + _BinaryFunctionConcept) public: // typedefs: @@ -142,7 +143,8 @@ namespace __gnu_norm // allocation/deallocation /// Default constructor creates no elements. - set() : _M_t(_Compare(), allocator_type()) {} + set() + : _M_t(_Compare(), allocator_type()) {} /** * @brief Default constructor creates no elements. @@ -152,7 +154,7 @@ namespace __gnu_norm */ explicit set(const _Compare& __comp, const allocator_type& __a = allocator_type()) - : _M_t(__comp, __a) {} + : _M_t(__comp, __a) {} /** * @brief Builds a %set from a range. @@ -164,9 +166,9 @@ namespace __gnu_norm * otherwise (where N is distance(first,last)). */ template - set(_InputIterator __first, _InputIterator __last) - : _M_t(_Compare(), allocator_type()) - { _M_t.insert_unique(__first, __last); } + set(_InputIterator __first, _InputIterator __last) + : _M_t(_Compare(), allocator_type()) + { _M_t.insert_unique(__first, __last); } /** * @brief Builds a %set from a range. @@ -180,10 +182,11 @@ namespace __gnu_norm * otherwise (where N is distance(first,last)). */ template - set(_InputIterator __first, _InputIterator __last, const _Compare& __comp, - const allocator_type& __a = allocator_type()) + set(_InputIterator __first, _InputIterator __last, + const _Compare& __comp, + const allocator_type& __a = allocator_type()) : _M_t(__comp, __a) - { _M_t.insert_unique(__first, __last); } + { _M_t.insert_unique(__first, __last); } /** * @brief Set copy constructor. @@ -192,7 +195,8 @@ namespace __gnu_norm * The newly-created %set uses a copy of the allocation object used * by @a x. */ - set(const set<_Key,_Compare,_Alloc>& __x) : _M_t(__x._M_t) {} + set(const set<_Key,_Compare,_Alloc>& __x) + : _M_t(__x._M_t) { } /** * @brief Set assignment operator. @@ -201,7 +205,8 @@ namespace __gnu_norm * All the elements of @a x are copied, but unlike the copy constructor, * the allocator object is not copied. */ - set<_Key,_Compare,_Alloc>& operator=(const set<_Key, _Compare, _Alloc>& __x) + set<_Key,_Compare,_Alloc>& + operator=(const set<_Key, _Compare, _Alloc>& __x) { _M_t = __x._M_t; return *this; @@ -210,45 +215,66 @@ namespace __gnu_norm // accessors: /// Returns the comparison object with which the %set was constructed. - key_compare key_comp() const { return _M_t.key_comp(); } + key_compare + key_comp() const + { return _M_t.key_comp(); } /// Returns the comparison object with which the %set was constructed. - value_compare value_comp() const { return _M_t.key_comp(); } + value_compare + value_comp() const + { return _M_t.key_comp(); } /// Returns the allocator object with which the %set was constructed. - allocator_type get_allocator() const { return _M_t.get_allocator(); } + allocator_type + get_allocator() const + { return _M_t.get_allocator(); } /** * Returns a read/write iterator that points to the first element in the * %set. Iteration is done in ascending order according to the keys. */ - iterator begin() const { return _M_t.begin(); } + iterator + begin() const + { return _M_t.begin(); } /** * Returns a read/write iterator that points one past the last element in * the %set. Iteration is done in ascending order according to the keys. */ - iterator end() const { return _M_t.end(); } + iterator + end() const + { return _M_t.end(); } /** - * Returns a read/write reverse iterator that points to the last element in - * the %set. Iteration is done in descending order according to the keys. + * Returns a read/write reverse iterator that points to the last element + * in the %set. Iteration is done in descending order according to the + * keys. */ - reverse_iterator rbegin() const { return _M_t.rbegin(); } + reverse_iterator + rbegin() const + { return _M_t.rbegin(); } /** - * Returns a read-only (constant) reverse iterator that points to the last - * pair in the %map. Iteration is done in descending order according to - * the keys. + * Returns a read-only (constant) reverse iterator that points to the + * last pair in the %map. Iteration is done in descending order + * according to the keys. */ - reverse_iterator rend() const { return _M_t.rend(); } + reverse_iterator + rend() const + { return _M_t.rend(); } /// Returns true if the %set is empty. - bool empty() const { return _M_t.empty(); } + bool + empty() const + { return _M_t.empty(); } /// Returns the size of the %set. - size_type size() const { return _M_t.size(); } + size_type + size() const + { return _M_t.size(); } /// Returns the maximum size of the %set. - size_type max_size() const { return _M_t.max_size(); } + size_type + max_size() const + { return _M_t.max_size(); } /** * @brief Swaps data with another %set. @@ -261,15 +287,17 @@ namespace __gnu_norm * Note that the global std::swap() function is specialized such that * std::swap(s1,s2) will feed to this function. */ - void swap(set<_Key,_Compare,_Alloc>& __x) { _M_t.swap(__x._M_t); } + void + swap(set<_Key,_Compare,_Alloc>& __x) + { _M_t.swap(__x._M_t); } // insert/erase /** * @brief Attempts to insert an element into the %set. * @param x Element to be inserted. * @return A pair, of which the first element is an iterator that points - * to the possibly inserted element, and the second is a bool that - * is true if the element was actually inserted. + * to the possibly inserted element, and the second is a bool + * that is true if the element was actually inserted. * * This function attempts to insert an element into the %set. A %set * relies on unique keys and thus an element is only inserted if it is @@ -277,9 +305,10 @@ namespace __gnu_norm * * Insertion requires logarithmic time. */ - pair insert(const value_type& __x) + pair + insert(const value_type& __x) { - pair __p = _M_t.insert_unique(__x); + pair __p = _M_t.insert_unique(__x); return pair(__p.first, __p.second); } @@ -302,7 +331,8 @@ namespace __gnu_norm * * Insertion requires logarithmic time (if the hint is not taken). */ - iterator insert(iterator __position, const value_type& __x) + iterator + insert(iterator __position, const value_type& __x) { typedef typename _Rep_type::iterator _Rep_iterator; return _M_t.insert_unique((_Rep_iterator&)__position, __x); @@ -317,7 +347,8 @@ namespace __gnu_norm * Complexity similar to that of the range constructor. */ template - void insert(_InputIterator __first, _InputIterator __last) + void + insert(_InputIterator __first, _InputIterator __last) { _M_t.insert_unique(__first, __last); } /** @@ -329,7 +360,8 @@ namespace __gnu_norm * that if the element is itself a pointer, the pointed-to memory is not * touched in any way. Managing the pointer is the user's responsibilty. */ - void erase(iterator __position) + void + erase(iterator __position) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__position); @@ -346,11 +378,13 @@ namespace __gnu_norm * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibilty. */ - size_type erase(const key_type& __x) { return _M_t.erase(__x); } + size_type + erase(const key_type& __x) { return _M_t.erase(__x); } /** * @brief Erases a [first,last) range of elements from a %set. - * @param first Iterator pointing to the start of the range to be erased. + * @param first Iterator pointing to the start of the range to be + * erased. * @param last Iterator pointing to the end of the range to be erased. * * This function erases a sequence of elements from a %set. @@ -358,7 +392,8 @@ namespace __gnu_norm * the element is itself a pointer, the pointed-to memory is not touched * in any way. Managing the pointer is the user's responsibilty. */ - void erase(iterator __first, iterator __last) + void + erase(iterator __first, iterator __last) { typedef typename _Rep_type::iterator _Rep_iterator; _M_t.erase((_Rep_iterator&)__first, (_Rep_iterator&)__last); @@ -370,7 +405,9 @@ namespace __gnu_norm * pointed-to memory is not touched in any way. Managing the pointer is * the user's responsibilty. */ - void clear() { _M_t.clear(); } + void + clear() + { _M_t.clear(); } // set operations: @@ -382,7 +419,8 @@ namespace __gnu_norm * This function only makes sense for multisets; for set the result will * either be 0 (not present) or 1 (present). */ - size_type count(const key_type& __x) const + size_type + count(const key_type& __x) const { return _M_t.find(__x) == _M_t.end() ? 0 : 1; } // _GLIBCXX_RESOLVE_LIB_DEFECTS @@ -399,8 +437,13 @@ namespace __gnu_norm * pointing to the sought after element. If unsuccessful it returns the * past-the-end ( @c end() ) iterator. */ - iterator find(const key_type& __x) { return _M_t.find(__x); } - const_iterator find(const key_type& __x) const { return _M_t.find(__x); } + iterator + find(const key_type& __x) + { return _M_t.find(__x); } + + const_iterator + find(const key_type& __x) const + { return _M_t.find(__x); } //@} //@{ @@ -415,9 +458,12 @@ namespace __gnu_norm * pointing to the first element that has a greater value than given key * or end() if no such element exists. */ - iterator lower_bound(const key_type& __x) + iterator + lower_bound(const key_type& __x) { return _M_t.lower_bound(__x); } - const_iterator lower_bound(const key_type& __x) const + + const_iterator + lower_bound(const key_type& __x) const { return _M_t.lower_bound(__x); } //@} @@ -428,9 +474,12 @@ namespace __gnu_norm * @return Iterator pointing to the first element * greater than key, or end(). */ - iterator upper_bound(const key_type& __x) + iterator + upper_bound(const key_type& __x) { return _M_t.upper_bound(__x); } - const_iterator upper_bound(const key_type& __x) const + + const_iterator + upper_bound(const key_type& __x) const { return _M_t.upper_bound(__x); } //@} @@ -450,16 +499,22 @@ namespace __gnu_norm * * This function probably only makes sense for multisets. */ - pair equal_range(const key_type& __x) + pair + equal_range(const key_type& __x) { return _M_t.equal_range(__x); } - pair equal_range(const key_type& __x) const + + pair + equal_range(const key_type& __x) const { return _M_t.equal_range(__x); } //@} template - friend bool operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + friend bool + operator== (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + template - friend bool operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); + friend bool + operator< (const set<_K1,_C1,_A1>&, const set<_K1,_C1,_A1>&); }; @@ -508,8 +563,7 @@ namespace __gnu_norm inline bool operator>(const set<_Key,_Compare,_Alloc>& __x, const set<_Key,_Compare,_Alloc>& __y) - { return __y < __x; } - + { return __y < __x; } /// Returns !(y < x) template