From: Phil Edwards Date: Thu, 18 Apr 2002 02:55:50 +0000 (+0000) Subject: doxygroups.cc: New group on binary searching. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bf551f96b1722b7310c29f3a00feecea8454c962;p=gcc.git doxygroups.cc: New group on binary searching. 2002-04-17 Phil Edwards * docs/doxygen/doxygroups.cc: New group on binary searching. * include/bits/stl_algo.h: Document binary searches and merges. * include/bits/stl_deque.h: The 'map' member is not the 'map' class. From-SVN: r52453 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 93bab515238..8b509cc627d 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,9 @@ +2002-04-17 Phil Edwards + + * docs/doxygen/doxygroups.cc: New group on binary searching. + * include/bits/stl_algo.h: Document binary searches and merges. + * include/bits/stl_deque.h: The 'map' member is not the 'map' class. + 2002-04-17 Phil Edwards * docs/doxygen/mainpage.html: Doxygen logo is now a PNG file. diff --git a/libstdc++-v3/docs/doxygen/doxygroups.cc b/libstdc++-v3/docs/doxygen/doxygroups.cc index da71879e8e5..ccf72049598 100644 --- a/libstdc++-v3/docs/doxygen/doxygroups.cc +++ b/libstdc++-v3/docs/doxygen/doxygroups.cc @@ -178,6 +178,36 @@ char* __cxa_demangle (const char* mangled_name, char* output_buffer, size_t* length, int* status); } // namespace abi +// // // // // // // // // // // // // // // // // // // // // // // // +/** @addtogroup binarysearch Binary search algorithms +These algorithms are variations of a classic binary search. They all assume +that the sequence being searched is already sorted. + +The number of comparisons will be logarithmic (and as few as possible). +The number of steps through the sequence will be logarithmic for +random-access iterators (e.g., pointers), and linear otherwise. + +The LWG has passed Defect Report 270, which notes: The proposed +resolution reinterprets binary search. Instead of thinking about searching +for a value in a sorted range, we view that as an important special +case of a more general algorithm: searching for the partition point in a +partitioned range. We also add a guarantee that the old wording did not: +we ensure that the upper bound is no earlier than the lower bound, that +the pair returned by equal_range is a valid range, and that the first part +of that pair is the lower bound. + +The actual effect of the first sentence is that a comparison functor +passed by the user doesn't necessarily need to induce a strict weak ordering +relation. Rather, it partitions the range. +*/ + +// // // // // // // // // // // // // // // // // // // // // // // // + +// // // // // // // // // // // // // // // // // // // // // // // // +/* * @addtogroup groupname description of group +placeholder text +*/ + // // // // // // // // // // // // // // // // // // // // // // // // // vim:et:noai: diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h index 4263e7711e8..009c409b6fb 100644 --- a/libstdc++-v3/include/bits/stl_algo.h +++ b/libstdc++-v3/include/bits/stl_algo.h @@ -2756,8 +2756,15 @@ __result, __binary_pred, _IterType()); } - // Binary search (lower_bound, upper_bound, equal_range, binary_search). - + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element "not less than" @a val. + * @ingroup binarysearch + */ template _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) @@ -2793,6 +2800,19 @@ __result, __binary_pred, _IterType()); return __first; } + /** + * @brief Finds the first position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ template _ForwardIter lower_bound(_ForwardIter __first, _ForwardIter __last, @@ -2824,6 +2844,15 @@ __result, __binary_pred, _IterType()); return __first; } + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An iterator pointing to the first element greater than @a val. + * @ingroup binarysearch + */ template _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) @@ -2856,6 +2885,19 @@ __result, __binary_pred, _IterType()); return __first; } + /** + * @brief Finds the last position in which @a val could be inserted + * without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element greater than @a val. + * @ingroup binarysearch + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ template _ForwardIter upper_bound(_ForwardIter __first, _ForwardIter __last, @@ -2887,6 +2929,22 @@ __result, __binary_pred, _IterType()); return __first; } + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val), + * upper_bound(first, last, val)) + * @endcode + * but does not actually call those functions. + */ template pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val) @@ -2925,6 +2983,23 @@ __result, __binary_pred, _IterType()); return pair<_ForwardIter, _ForwardIter>(__first, __first); } + /** + * @brief Finds the largest subrange in which @a val could be inserted + * at any place in it without changing the ordering. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return An pair of iterators defining the subrange. + * @ingroup binarysearch + * + * This is equivalent to + * @code + * std::make_pair(lower_bound(first, last, val, comp), + * upper_bound(first, last, val, comp)) + * @endcode + * but does not actually call those functions. + */ template pair<_ForwardIter, _ForwardIter> equal_range(_ForwardIter __first, _ForwardIter __last, const _Tp& __val, @@ -2963,6 +3038,17 @@ __result, __binary_pred, _IterType()); return pair<_ForwardIter, _ForwardIter>(__first, __first); } + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + */ template bool binary_search(_ForwardIter __first, _ForwardIter __last, @@ -2979,6 +3065,21 @@ __result, __binary_pred, _IterType()); return __i != __last && !(__val < *__i); } + /** + * @brief Determines whether an element exists in a range. + * @param first An iterator. + * @param last Another iterator. + * @param val The search term. + * @param comp A functor to use for comparisons. + * @return True if @a val (or its equivelent) is in [@a first,@a last ]. + * @ingroup binarysearch + * + * Note that this does not actually return an iterator to @a val. For + * that, use std::find or a container's specialized find member functions. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ template bool binary_search(_ForwardIter __first, _ForwardIter __last, @@ -2995,8 +3096,22 @@ __result, __binary_pred, _IterType()); return __i != __last && !__comp(__val, *__i); } - // merge, with and without an explicitly supplied comparison function. - + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + */ template _OutputIter merge(_InputIter1 __first1, _InputIter1 __last1, @@ -3028,6 +3143,26 @@ __result, __binary_pred, _IterType()); return copy(__first2, __last2, copy(__first1, __last1, __result)); } + /** + * @brief Merges two sorted ranges. + * @param first1 An iterator. + * @param first2 Another iterator. + * @param last1 Another iterator. + * @param last2 Another iterator. + * @param result An iterator pointing to the end of the merged range. + * @param comp A functor to use for comparisons. + * @return An iterator pointing to the first element "not less than" @a val. + * + * Merges the ranges [first1,last1) and [first2,last2) into the sorted range + * [result, result + (last1-first1) + (last2-first2)). Both input ranges + * must be sorted, and the output range must not overlap with either of + * the input ranges. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ template _OutputIter @@ -3061,8 +3196,11 @@ __result, __binary_pred, _IterType()); return copy(__first2, __last2, copy(__first1, __last1, __result)); } - // inplace_merge and its auxiliary functions. - + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template void __merge_without_buffer(_BidirectionalIter __first, @@ -3102,6 +3240,11 @@ __result, __binary_pred, _IterType()); __len1 - __len11, __len2 - __len22); } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template void __merge_without_buffer(_BidirectionalIter __first, @@ -3142,6 +3285,11 @@ __result, __binary_pred, _IterType()); __len1 - __len11, __len2 - __len22, __comp); } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template _BidirectionalIter1 @@ -3170,6 +3318,11 @@ __result, __binary_pred, _IterType()); } } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template _BidirectionalIter3 @@ -3199,6 +3352,11 @@ __result, __binary_pred, _IterType()); } } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template _BidirectionalIter3 @@ -3229,6 +3387,11 @@ __result, __binary_pred, _IterType()); } } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template void __merge_adaptive(_BidirectionalIter __first, @@ -3273,6 +3436,11 @@ __result, __binary_pred, _IterType()); } } + /** + * @if maint + * This is a helper function for the merge routines. + * @endif + */ template void @@ -3320,6 +3488,23 @@ __result, __binary_pred, _IterType()); } } + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + */ template void inplace_merge(_BidirectionalIter __first, @@ -3350,6 +3535,27 @@ __result, __binary_pred, _IterType()); __buf.begin(), _DistanceType(__buf.size())); } + /** + * @brief Merges two sorted ranges in place. + * @param first An iterator. + * @param middle Another iterator. + * @param last Another iterator. + * @param comp A functor to use for comparisons. + * @return Nothing. + * + * Merges two sorted and consecutive ranges, [first,middle) and + * [middle,last), and puts the result in [first,last). The output will + * be sorted. The sort is @e stable, that is, for equivalent + * elements in the two ranges, elements from the first range will always + * come before elements from the second. + * + * If enough additional memory is available, this takes (last-first)-1 + * comparisons. Otherwise an NlogN algorithm is used, where N is + * distance(first,last). + * + * The comparison function should have the same effects on ordering as + * the function used for the initial sort. + */ template void inplace_merge(_BidirectionalIter __first, diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 5cd62b7291f..5fa8d125e75 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -437,7 +437,8 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) * - size_t _M_map_size * - iterator _M_start, _M_finish * - * map_size is at least 8. map is an array of map_size pointers-to-"nodes". + * map_size is at least 8. %map is an array of map_size pointers-to-"nodes". + * (The name has nothing to do with the std::map class.) * * A "node" has no specific type name as such, but it is referred to as * "node" in this file. It is a simple array-of-Tp. If Tp is very large, @@ -451,18 +452,18 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) * memory pool. There are 20 hours left in the year; perhaps I can fix * this before 2002. * - * Not every pointer in the map array will point to a node. If the initial - * number of elements in the deque is small, the /middle/ map pointers will + * Not every pointer in the %map array will point to a node. If the initial + * number of elements in the deque is small, the /middle/ %map pointers will * be valid, and the ones at the edges will be unused. This same situation - * will arise as the map grows: available map pointers, if any, will be on - * the ends. As new nodes are created, only a subset of the map's pointers + * will arise as the %map grows: available %map pointers, if any, will be on + * the ends. As new nodes are created, only a subset of the %map's pointers * need to be copied "outward". * * Class invariants: * - For any nonsingular iterator i: - * - i.node points to a member of the map array. (Yes, you read that + * - i.node points to a member of the %map array. (Yes, you read that * correctly: i.node does not actually point to a node.) The member of - * the map array is what actually points to the node. + * the %map array is what actually points to the node. * - i.first == *(i.node) (This points to the node (first Tp element).) * - i.last == i.first + node_size * - i.cur is a pointer in the range [i.first, i.last). NOTE: @@ -478,10 +479,10 @@ _Deque_base<_Tp,_Alloc>::_M_destroy_nodes(_Tp** __nstart, _Tp** __nfinish) * that range are uninitialized storage. Otherwise, [start.cur, start.last) * and [finish.first, finish.cur) are initialized objects, and [start.first, * start.cur) and [finish.cur, finish.last) are uninitialized storage. - * - [map, map + map_size) is a valid, non-empty range. + * - [%map, %map + map_size) is a valid, non-empty range. * - [start.node, finish.node] is a valid range contained within - * [map, map + map_size). - * - A pointer in the range [map, map + map_size) points to an allocated node + * [%map, %map + map_size). + * - A pointer in the range [%map, %map + map_size) points to an allocated node * if and only if the pointer is in the range [start.node, finish.node]. * * Here's the magic: nothing in deque is "aware" of the discontiguous storage!