00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef BINARY_SEARCH_DWA_122600_H_
00029 # define BINARY_SEARCH_DWA_122600_H_
00030
00031 # include <boost/detail/iterator.hpp>
00032 # include <utility>
00033
00034 namespace boost { namespace detail {
00035
00036 template <class ForwardIter, class Tp>
00037 ForwardIter lower_bound(ForwardIter first, ForwardIter last,
00038 const Tp& val)
00039 {
00040 typedef detail::iterator_traits<ForwardIter> traits;
00041
00042 typename traits::difference_type len = boost::detail::distance(first, last);
00043 typename traits::difference_type half;
00044 ForwardIter middle;
00045
00046 while (len > 0) {
00047 half = len >> 1;
00048 middle = first;
00049 std::advance(middle, half);
00050 if (*middle < val) {
00051 first = middle;
00052 ++first;
00053 len = len - half - 1;
00054 }
00055 else
00056 len = half;
00057 }
00058 return first;
00059 }
00060
00061 template <class ForwardIter, class Tp, class Compare>
00062 ForwardIter lower_bound(ForwardIter first, ForwardIter last,
00063 const Tp& val, Compare comp)
00064 {
00065 typedef detail::iterator_traits<ForwardIter> traits;
00066
00067 typename traits::difference_type len = boost::detail::distance(first, last);
00068 typename traits::difference_type half;
00069 ForwardIter middle;
00070
00071 while (len > 0) {
00072 half = len >> 1;
00073 middle = first;
00074 std::advance(middle, half);
00075 if (comp(*middle, val)) {
00076 first = middle;
00077 ++first;
00078 len = len - half - 1;
00079 }
00080 else
00081 len = half;
00082 }
00083 return first;
00084 }
00085
00086 template <class ForwardIter, class Tp>
00087 ForwardIter upper_bound(ForwardIter first, ForwardIter last,
00088 const Tp& val)
00089 {
00090 typedef detail::iterator_traits<ForwardIter> traits;
00091
00092 typename traits::difference_type len = boost::detail::distance(first, last);
00093 typename traits::difference_type half;
00094 ForwardIter middle;
00095
00096 while (len > 0) {
00097 half = len >> 1;
00098 middle = first;
00099 std::advance(middle, half);
00100 if (val < *middle)
00101 len = half;
00102 else {
00103 first = middle;
00104 ++first;
00105 len = len - half - 1;
00106 }
00107 }
00108 return first;
00109 }
00110
00111 template <class ForwardIter, class Tp, class Compare>
00112 ForwardIter upper_bound(ForwardIter first, ForwardIter last,
00113 const Tp& val, Compare comp)
00114 {
00115 typedef detail::iterator_traits<ForwardIter> traits;
00116
00117 typename traits::difference_type len = boost::detail::distance(first, last);
00118 typename traits::difference_type half;
00119 ForwardIter middle;
00120
00121 while (len > 0) {
00122 half = len >> 1;
00123 middle = first;
00124 std::advance(middle, half);
00125 if (comp(val, *middle))
00126 len = half;
00127 else {
00128 first = middle;
00129 ++first;
00130 len = len - half - 1;
00131 }
00132 }
00133 return first;
00134 }
00135
00136 template <class ForwardIter, class Tp>
00137 std::pair<ForwardIter, ForwardIter>
00138 equal_range(ForwardIter first, ForwardIter last, const Tp& val)
00139 {
00140 typedef detail::iterator_traits<ForwardIter> traits;
00141
00142 typename traits::difference_type len = boost::detail::distance(first, last);
00143 typename traits::difference_type half;
00144 ForwardIter middle, left, right;
00145
00146 while (len > 0) {
00147 half = len >> 1;
00148 middle = first;
00149 std::advance(middle, half);
00150 if (*middle < val) {
00151 first = middle;
00152 ++first;
00153 len = len - half - 1;
00154 }
00155 else if (val < *middle)
00156 len = half;
00157 else {
00158 left = boost::detail::lower_bound(first, middle, val);
00159 std::advance(first, len);
00160 right = boost::detail::upper_bound(++middle, first, val);
00161 return std::pair<ForwardIter, ForwardIter>(left, right);
00162 }
00163 }
00164 return std::pair<ForwardIter, ForwardIter>(first, first);
00165 }
00166
00167 template <class ForwardIter, class Tp, class Compare>
00168 std::pair<ForwardIter, ForwardIter>
00169 equal_range(ForwardIter first, ForwardIter last, const Tp& val,
00170 Compare comp)
00171 {
00172 typedef detail::iterator_traits<ForwardIter> traits;
00173
00174 typename traits::difference_type len = boost::detail::distance(first, last);
00175 typename traits::difference_type half;
00176 ForwardIter middle, left, right;
00177
00178 while (len > 0) {
00179 half = len >> 1;
00180 middle = first;
00181 std::advance(middle, half);
00182 if (comp(*middle, val)) {
00183 first = middle;
00184 ++first;
00185 len = len - half - 1;
00186 }
00187 else if (comp(val, *middle))
00188 len = half;
00189 else {
00190 left = boost::detail::lower_bound(first, middle, val, comp);
00191 std::advance(first, len);
00192 right = boost::detail::upper_bound(++middle, first, val, comp);
00193 return std::pair<ForwardIter, ForwardIter>(left, right);
00194 }
00195 }
00196 return std::pair<ForwardIter, ForwardIter>(first, first);
00197 }
00198
00199 template <class ForwardIter, class Tp>
00200 bool binary_search(ForwardIter first, ForwardIter last,
00201 const Tp& val) {
00202 ForwardIter i = boost::detail::lower_bound(first, last, val);
00203 return i != last && !(val < *i);
00204 }
00205
00206 template <class ForwardIter, class Tp, class Compare>
00207 bool binary_search(ForwardIter first, ForwardIter last,
00208 const Tp& val,
00209 Compare comp) {
00210 ForwardIter i = boost::detail::lower_bound(first, last, val, comp);
00211 return i != last && !comp(val, *i);
00212 }
00213
00214 }}
00215
00216 #endif // BINARY_SEARCH_DWA_122600_H_