binary_search.hpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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. # include <utility>
  31. # include <iterator>
  32. namespace boost { namespace detail {
  33. template <class ForwardIter, class Tp>
  34. ForwardIter lower_bound(ForwardIter first, ForwardIter last,
  35. const Tp& val)
  36. {
  37. typedef std::iterator_traits<ForwardIter> traits;
  38. typename traits::difference_type len = std::distance(first, last);
  39. typename traits::difference_type half;
  40. ForwardIter middle;
  41. while (len > 0) {
  42. half = len >> 1;
  43. middle = first;
  44. std::advance(middle, half);
  45. if (*middle < val) {
  46. first = middle;
  47. ++first;
  48. len = len - half - 1;
  49. }
  50. else
  51. len = half;
  52. }
  53. return first;
  54. }
  55. template <class ForwardIter, class Tp, class Compare>
  56. ForwardIter lower_bound(ForwardIter first, ForwardIter last,
  57. const Tp& val, Compare comp)
  58. {
  59. typedef std::iterator_traits<ForwardIter> traits;
  60. typename traits::difference_type len = std::distance(first, last);
  61. typename traits::difference_type half;
  62. ForwardIter middle;
  63. while (len > 0) {
  64. half = len >> 1;
  65. middle = first;
  66. std::advance(middle, half);
  67. if (comp(*middle, val)) {
  68. first = middle;
  69. ++first;
  70. len = len - half - 1;
  71. }
  72. else
  73. len = half;
  74. }
  75. return first;
  76. }
  77. template <class ForwardIter, class Tp>
  78. ForwardIter upper_bound(ForwardIter first, ForwardIter last,
  79. const Tp& val)
  80. {
  81. typedef std::iterator_traits<ForwardIter> traits;
  82. typename traits::difference_type len = std::distance(first, last);
  83. typename traits::difference_type half;
  84. ForwardIter middle;
  85. while (len > 0) {
  86. half = len >> 1;
  87. middle = first;
  88. std::advance(middle, half);
  89. if (val < *middle)
  90. len = half;
  91. else {
  92. first = middle;
  93. ++first;
  94. len = len - half - 1;
  95. }
  96. }
  97. return first;
  98. }
  99. template <class ForwardIter, class Tp, class Compare>
  100. ForwardIter upper_bound(ForwardIter first, ForwardIter last,
  101. const Tp& val, Compare comp)
  102. {
  103. typedef std::iterator_traits<ForwardIter> traits;
  104. typename traits::difference_type len = std::distance(first, last);
  105. typename traits::difference_type half;
  106. ForwardIter middle;
  107. while (len > 0) {
  108. half = len >> 1;
  109. middle = first;
  110. std::advance(middle, half);
  111. if (comp(val, *middle))
  112. len = half;
  113. else {
  114. first = middle;
  115. ++first;
  116. len = len - half - 1;
  117. }
  118. }
  119. return first;
  120. }
  121. template <class ForwardIter, class Tp>
  122. std::pair<ForwardIter, ForwardIter>
  123. equal_range(ForwardIter first, ForwardIter last, const Tp& val)
  124. {
  125. typedef std::iterator_traits<ForwardIter> traits;
  126. typename traits::difference_type len = std::distance(first, last);
  127. typename traits::difference_type half;
  128. ForwardIter middle, left, right;
  129. while (len > 0) {
  130. half = len >> 1;
  131. middle = first;
  132. std::advance(middle, half);
  133. if (*middle < val) {
  134. first = middle;
  135. ++first;
  136. len = len - half - 1;
  137. }
  138. else if (val < *middle)
  139. len = half;
  140. else {
  141. left = boost::detail::lower_bound(first, middle, val);
  142. std::advance(first, len);
  143. right = boost::detail::upper_bound(++middle, first, val);
  144. return std::pair<ForwardIter, ForwardIter>(left, right);
  145. }
  146. }
  147. return std::pair<ForwardIter, ForwardIter>(first, first);
  148. }
  149. template <class ForwardIter, class Tp, class Compare>
  150. std::pair<ForwardIter, ForwardIter>
  151. equal_range(ForwardIter first, ForwardIter last, const Tp& val,
  152. Compare comp)
  153. {
  154. typedef std::iterator_traits<ForwardIter> traits;
  155. typename traits::difference_type len = std::distance(first, last);
  156. typename traits::difference_type half;
  157. ForwardIter middle, left, right;
  158. while (len > 0) {
  159. half = len >> 1;
  160. middle = first;
  161. std::advance(middle, half);
  162. if (comp(*middle, val)) {
  163. first = middle;
  164. ++first;
  165. len = len - half - 1;
  166. }
  167. else if (comp(val, *middle))
  168. len = half;
  169. else {
  170. left = boost::detail::lower_bound(first, middle, val, comp);
  171. std::advance(first, len);
  172. right = boost::detail::upper_bound(++middle, first, val, comp);
  173. return std::pair<ForwardIter, ForwardIter>(left, right);
  174. }
  175. }
  176. return std::pair<ForwardIter, ForwardIter>(first, first);
  177. }
  178. template <class ForwardIter, class Tp>
  179. bool binary_search(ForwardIter first, ForwardIter last,
  180. const Tp& val) {
  181. ForwardIter i = boost::detail::lower_bound(first, last, val);
  182. return i != last && !(val < *i);
  183. }
  184. template <class ForwardIter, class Tp, class Compare>
  185. bool binary_search(ForwardIter first, ForwardIter last,
  186. const Tp& val,
  187. Compare comp) {
  188. ForwardIter i = boost::detail::lower_bound(first, last, val, comp);
  189. return i != last && !comp(val, *i);
  190. }
  191. }} // namespace boost::detail
  192. #endif // BINARY_SEARCH_DWA_122600_H_