1 // Copyright (c) 2000 David Abrahams. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 // 6 // Copyright (c) 1994 7 // Hewlett-Packard Company 8 // 9 // Permission to use, copy, modify, distribute and sell this software 10 // and its documentation for any purpose is hereby granted without fee, 11 // provided that the above copyright notice appear in all copies and 12 // that both that copyright notice and this permission notice appear 13 // in supporting documentation. Hewlett-Packard Company makes no 14 // representations about the suitability of this software for any 15 // purpose. It is provided "as is" without express or implied warranty. 16 // 17 // Copyright (c) 1996 18 // Silicon Graphics Computer Systems, Inc. 19 // 20 // Permission to use, copy, modify, distribute and sell this software 21 // and its documentation for any purpose is hereby granted without fee, 22 // provided that the above copyright notice appear in all copies and 23 // that both that copyright notice and this permission notice appear 24 // in supporting documentation. Silicon Graphics makes no 25 // representations about the suitability of this software for any 26 // purpose. It is provided "as is" without express or implied warranty. 27 // 28 #ifndef BINARY_SEARCH_DWA_122600_H_ 29 # define BINARY_SEARCH_DWA_122600_H_ 30 31 # include <boost/detail/iterator.hpp> 32 # include <utility> 33 34 namespace boost { namespace detail { 35 36 template <class ForwardIter, class Tp> 37 ForwardIter lower_bound(ForwardIter first, ForwardIter last, 38 const Tp& val) 39 { 40 typedef detail::iterator_traits<ForwardIter> traits; 41 42 typename traits::difference_type len = boost::detail::distance(first, last); 43 typename traits::difference_type half; 44 ForwardIter middle; 45 46 while (len > 0) { 47 half = len >> 1; 48 middle = first; 49 std::advance(middle, half); 50 if (*middle < val) { 51 first = middle; 52 ++first; 53 len = len - half - 1; 54 } 55 else 56 len = half; 57 } 58 return first; 59 } 60 61 template <class ForwardIter, class Tp, class Compare> 62 ForwardIter lower_bound(ForwardIter first, ForwardIter last, 63 const Tp& val, Compare comp) 64 { 65 typedef detail::iterator_traits<ForwardIter> traits; 66 67 typename traits::difference_type len = boost::detail::distance(first, last); 68 typename traits::difference_type half; 69 ForwardIter middle; 70 71 while (len > 0) { 72 half = len >> 1; 73 middle = first; 74 std::advance(middle, half); 75 if (comp(*middle, val)) { 76 first = middle; 77 ++first; 78 len = len - half - 1; 79 } 80 else 81 len = half; 82 } 83 return first; 84 } 85 86 template <class ForwardIter, class Tp> 87 ForwardIter upper_bound(ForwardIter first, ForwardIter last, 88 const Tp& val) 89 { 90 typedef detail::iterator_traits<ForwardIter> traits; 91 92 typename traits::difference_type len = boost::detail::distance(first, last); 93 typename traits::difference_type half; 94 ForwardIter middle; 95 96 while (len > 0) { 97 half = len >> 1; 98 middle = first; 99 std::advance(middle, half); 100 if (val < *middle) 101 len = half; 102 else { 103 first = middle; 104 ++first; 105 len = len - half - 1; 106 } 107 } 108 return first; 109 } 110 111 template <class ForwardIter, class Tp, class Compare> 112 ForwardIter upper_bound(ForwardIter first, ForwardIter last, 113 const Tp& val, Compare comp) 114 { 115 typedef detail::iterator_traits<ForwardIter> traits; 116 117 typename traits::difference_type len = boost::detail::distance(first, last); 118 typename traits::difference_type half; 119 ForwardIter middle; 120 121 while (len > 0) { 122 half = len >> 1; 123 middle = first; 124 std::advance(middle, half); 125 if (comp(val, *middle)) 126 len = half; 127 else { 128 first = middle; 129 ++first; 130 len = len - half - 1; 131 } 132 } 133 return first; 134 } 135 136 template <class ForwardIter, class Tp> 137 std::pair<ForwardIter, ForwardIter> 138 equal_range(ForwardIter first, ForwardIter last, const Tp& val) 139 { 140 typedef detail::iterator_traits<ForwardIter> traits; 141 142 typename traits::difference_type len = boost::detail::distance(first, last); 143 typename traits::difference_type half; 144 ForwardIter middle, left, right; 145 146 while (len > 0) { 147 half = len >> 1; 148 middle = first; 149 std::advance(middle, half); 150 if (*middle < val) { 151 first = middle; 152 ++first; 153 len = len - half - 1; 154 } 155 else if (val < *middle) 156 len = half; 157 else { 158 left = boost::detail::lower_bound(first, middle, val); 159 std::advance(first, len); 160 right = boost::detail::upper_bound(++middle, first, val); 161 return std::pair<ForwardIter, ForwardIter>(left, right); 162 } 163 } 164 return std::pair<ForwardIter, ForwardIter>(first, first); 165 } 166 167 template <class ForwardIter, class Tp, class Compare> 168 std::pair<ForwardIter, ForwardIter> 169 equal_range(ForwardIter first, ForwardIter last, const Tp& val, 170 Compare comp) 171 { 172 typedef detail::iterator_traits<ForwardIter> traits; 173 174 typename traits::difference_type len = boost::detail::distance(first, last); 175 typename traits::difference_type half; 176 ForwardIter middle, left, right; 177 178 while (len > 0) { 179 half = len >> 1; 180 middle = first; 181 std::advance(middle, half); 182 if (comp(*middle, val)) { 183 first = middle; 184 ++first; 185 len = len - half - 1; 186 } 187 else if (comp(val, *middle)) 188 len = half; 189 else { 190 left = boost::detail::lower_bound(first, middle, val, comp); 191 std::advance(first, len); 192 right = boost::detail::upper_bound(++middle, first, val, comp); 193 return std::pair<ForwardIter, ForwardIter>(left, right); 194 } 195 } 196 return std::pair<ForwardIter, ForwardIter>(first, first); 197 } 198 199 template <class ForwardIter, class Tp> 200 bool binary_search(ForwardIter first, ForwardIter last, 201 const Tp& val) { 202 ForwardIter i = boost::detail::lower_bound(first, last, val); 203 return i != last && !(val < *i); 204 } 205 206 template <class ForwardIter, class Tp, class Compare> 207 bool binary_search(ForwardIter first, ForwardIter last, 208 const Tp& val, 209 Compare comp) { 210 ForwardIter i = boost::detail::lower_bound(first, last, val, comp); 211 return i != last && !comp(val, *i); 212 } 213 214 }} // namespace boost::detail 215 216 #endif // BINARY_SEARCH_DWA_122600_H_ 217