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