binary_search.hpp
Go to the documentation of this file.
00001 // Copyright (c)  2000 David Abrahams. 
00002 // Distributed under the Boost Software License, Version 1.0. 
00003 // (See accompanying file LICENSE_1_0.txt or copy at 
00004 // http://www.boost.org/LICENSE_1_0.txt)
00005 // 
00006 // Copyright (c) 1994
00007 // Hewlett-Packard Company
00008 // 
00009 // Permission to use, copy, modify, distribute and sell this software
00010 // and its documentation for any purpose is hereby granted without fee,
00011 // provided that the above copyright notice appear in all copies and
00012 // that both that copyright notice and this permission notice appear
00013 // in supporting documentation.  Hewlett-Packard Company makes no
00014 // representations about the suitability of this software for any
00015 // purpose.  It is provided "as is" without express or implied warranty.
00016 // 
00017 // Copyright (c) 1996
00018 // Silicon Graphics Computer Systems, Inc.
00019 // 
00020 // Permission to use, copy, modify, distribute and sell this software
00021 // and its documentation for any purpose is hereby granted without fee,
00022 // provided that the above copyright notice appear in all copies and
00023 // that both that copyright notice and this permission notice appear
00024 // in supporting documentation.  Silicon Graphics makes no
00025 // representations about the suitability of this software for any
00026 // purpose.  It is provided "as is" without express or implied warranty.
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 }} // namespace boost::detail
00215 
00216 #endif // BINARY_SEARCH_DWA_122600_H_


appl
Author(s): petercai
autogenerated on Tue Jan 7 2014 11:02:28