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