00001
00002 #ifndef _INSTIGATE_STL_INTERNAL_HEADER_IN_ALGORITHM
00003 #error This is an internal header file used to implement Instigate STL.\
00004 It should never be included directly by a program.
00005 #endif
00006
00007 #ifndef INSTIGATE_STL_UPPER_BOUND_HPP
00008 #define INSTIGATE_STL_UPPER_BOUND_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_basis.hpp"
00062 #include "_distance.hpp"
00063 #include "_advance.hpp"
00064
00065
00066 #include <generic/base.hpp>
00067
00068
00069
00070
00071 namespace instigate {
00072 namespace stl {
00073 namespace implementation {
00074 template <typename F, typename L, typename D>
00075 F upper_bound_aux(F b, F e, const L& v, D*);
00076 template <typename F, typename L, typename C, typename D>
00077 F upper_bound_aux(F b, F e, const L& v, C c, D*);
00078 }
00079 template <typename F, typename L>
00080 inline F upper_bound(F b, F e, const L& v);
00081 template <typename F, typename L, typename C>
00082 inline F upper_bound(F b, F e, const L& v, C c);
00083 }
00084 }
00085
00129 template <typename F, typename L>
00130 inline F instigate::stl::upper_bound(F b, F e, const L& v)
00131 {
00132 namespace FI = instigate::stl::forward_iterator;
00133 typedef typename instigate::stl::readable_iterator::interface<F>::
00134 value_type value_type;
00135 CHECK(FI::requirements<F>);
00136 CHECK(instigate::stl::readable_iterator::requirements<F>);
00137 CHECK(instigate::generic::less_than_comparable::requirements<L>);
00138 CHECK_SAME_TYPE(value_type, L);
00139 typename FI::interface<F>::difference_type* k = 0;
00140 return instigate::stl::implementation::upper_bound_aux(b, e, v, k);
00141 }
00142
00147 template <typename F, typename L, typename D>
00148 F instigate::stl::implementation::upper_bound_aux(F b, F e, const L& v, D*)
00149 {
00150 namespace FI = instigate::stl::forward_iterator;
00151 typedef typename FI::interface<F>::difference_type difference_type;
00152 CHECK_CONVERTIBILITY(D, difference_type);
00153 D len = 0;
00154 assign(len, instigate::stl::distance(b, e));
00155 D half;
00156 char k[sizeof(F)];
00157 F* middle = 0;
00158 assign(middle, initialize<F>(k));
00159 while (0 < len) {
00160 assert(0 != middle);
00161 assign(half, len >> 1);
00162 assign(*middle, b);
00163 instigate::stl::advance(*middle, half);
00164 if (less_than(v, const_dereference(*middle))) {
00165 assign(len, half);
00166 } else {
00167 assign(b, *middle);
00168 increment(b);
00169 assign(len, len - half - 1);
00170 }
00171 }
00172 return b;
00173 }
00174
00222 template <typename F, typename L, typename C>
00223 inline F instigate::stl::upper_bound(F b, F e, const L& v, C c)
00224 {
00225 namespace FI = instigate::stl::forward_iterator;
00226 typedef typename instigate::stl::readable_iterator::interface<F>::
00227 value_type value_type;
00228 CHECK(FI::requirements<F>);
00229 CHECK(instigate::stl::readable_iterator::requirements<F>);
00230 CHECK(instigate::generic::less_than_comparable::requirements<L>);
00231 CHECK(instigate::stl::binary_predicate::requirements<C>);
00232 CHECK_SAME_TYPE(value_type, L);
00233 typename FI::interface<F>::difference_type* k = 0;
00234 return instigate::stl::implementation::upper_bound_aux(b, e, v, c, k);
00235 }
00236
00241 template <typename F, typename L, typename C, typename D>
00242 F instigate::stl::implementation::upper_bound_aux(F b, F e, const L& v, C c, D*)
00243 {
00244 namespace FI = instigate::stl::forward_iterator;
00245 typedef typename FI::interface<F>::difference_type difference_type;
00246 CHECK_CONVERTIBILITY(D, difference_type);
00247 D len = 0;
00248 assign(len, instigate::stl::distance(b, e));
00249 D half;
00250 char k[sizeof(F)];
00251 F* middle = 0;
00252 assign(middle, initialize<F>(k));
00253 while (0 < len) {
00254 assert(0 != middle);
00255 assign(half, len >> 1);
00256 assign(*middle, b);
00257 instigate::stl::advance(*middle, half);
00258 if (invoke_predicate(c, v, const_dereference(*middle))) {
00259 assign(len, half);
00260 } else {
00261 assign(b, *middle);
00262 increment(b);
00263 assign(len, len - half - 1);
00264 }
00265 }
00266 return b;
00267 }
00268
00269
00270
00271 #endif // INSTIGATE_STL_UPPER_BOUND_HPP