Home | History | Annotate | Download | only in detail
      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