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_EQUAL_RANGE_HPP
00008 #define INSTIGATE_STL_EQUAL_RANGE_HPP
00009
00062
00063 #include "concept.hpp"
00064 #include "_basis.hpp"
00065 #include "_advance.hpp"
00066 #include "_distance.hpp"
00067 #include "_lower_bound.hpp"
00068 #include "_upper_bound.hpp"
00069
00070
00071
00072
00073
00074 namespace instigate {
00075 namespace stl {
00076 namespace implementation {
00077 template <typename F, typename L, typename D, typename P>
00078 void equal_range_aux(F b, F e, const L& v, D*,
00079 P& p);
00080 template <typename F, typename L, typename C, typename D,
00081 typename P>
00082 void equal_range_aux(F b, F e, const L& v, C c,
00083 D*, P& p);
00084 }
00085 template <typename F, typename L, typename P>
00086 inline void equal_range(F b, F e, const L& v, P& p);
00087 template <typename F, typename L, typename C, typename P>
00088 inline void equal_range(F b, F e, const L& v, C c, P& p);
00089 }
00090 }
00091
00134 template <typename F, typename L, typename P>
00135 inline void instigate::stl::equal_range(F b, F e, const L& v, P& p)
00136 {
00137 namespace FI = instigate::stl::forward_iterator;
00138 typedef typename instigate::stl::readable_iterator::interface<F>::
00139 value_type value_type;
00140 CHECK(FI::requirements<F>);
00141 CHECK(instigate::stl::readable_iterator::requirements<F>);
00142 CHECK_SAME_TYPE(value_type, L);
00143 CHECK(instigate::stl::pair::requirements<P>);
00144 typename FI::interface<F>::difference_type* k = 0;
00145 instigate::stl::implementation::equal_range_aux(b, e, v, k, p);
00146 }
00147
00149 template <typename F, typename L, typename D, typename P>
00150 void instigate::stl::implementation::
00151 equal_range_aux(F b, F e, const L& v, D*, P& p)
00152 {
00153 namespace FI = instigate::stl::forward_iterator;
00154 typedef typename FI::interface<F>::difference_type difference_type;
00155 CHECK_CONVERTIBILITY(D, difference_type);
00156 D len = 0;
00157 assign(len, instigate::stl::distance(b, e));
00158 D half;
00159 char k[sizeof(F)];
00160 F* middle = 0;
00161 assign(middle, initialize<F>(k));
00162 char k1[sizeof(F)];
00163 F* left = 0;
00164 assign(left, initialize<F>(k1));
00165 char k2[sizeof(F)];
00166 F* right = 0;
00167 assign(right, initialize<F>(k2));
00168 while (0 < len) {
00169 assign(half, len >> 1);
00170 assert(0 != middle);
00171 assign(*middle, b);
00172 instigate::stl::advance(*middle, half);
00173 if (less_than(const_dereference(*middle), v)) {
00174 assign(b, *middle);
00175 increment(b);
00176 assign(len, len - half -1);
00177 } else {
00178 if (less_than(v, const_dereference(*middle))) {
00179 assign(len, half);
00180 } else {
00181 assert(0 != left);
00182 assign(*left, instigate::stl::lower_bound(b,
00183 *middle, v));
00184 instigate::stl::advance(b, len);
00185 increment(*middle);
00186 assert(0 != right);
00187 assign(*right, instigate::stl::
00188 upper_bound(*middle, b, v));
00189 assign(p.first, *left);
00190 assign(p.second, *right);
00191 return;
00192 }
00193 }
00194 }
00195 assign(p.first, b);
00196 assign(p.second, b);
00197 }
00198
00244 template <typename F, typename L, typename C, typename P>
00245 inline void instigate::stl::
00246 equal_range(F b, F e, const L& v, C c, P& p)
00247 {
00248 namespace FI = instigate::stl::forward_iterator;
00249 namespace PR = instigate::stl::pair;
00250 typedef typename instigate::stl::readable_iterator::interface<F>::
00251 value_type value_type;
00252 CHECK(FI::requirements<F>);
00253 CHECK(instigate::stl::readable_iterator::requirements<F>);
00254 CHECK(instigate::stl::pair::requirements<P>);
00255 CHECK_SAME_TYPE(value_type, L);
00256 typename FI::interface<F>::difference_type* k = 0;
00257 instigate::stl::implementation::equal_range_aux(b, e, v, c, k, p);
00258 }
00259
00261 template <typename F, typename L, typename C, typename D, typename P>
00262 void instigate::stl::implementation::equal_range_aux(F b, F e, const L& v, C c,
00263 D*, P& p)
00264 {
00265 namespace FI = instigate::stl::forward_iterator;
00266 typedef typename FI::interface<F>::difference_type difference_type;
00267 CHECK_CONVERTIBILITY(D, difference_type);
00268 D len = 0;
00269 assign(len, instigate::stl::distance(b, e));
00270 D half = 0;
00271 char k[sizeof(F)];
00272 F* middle = 0;
00273 assign(middle, initialize<F>(k));
00274 char k1[sizeof(F)];
00275 F* left = 0;
00276 assign(left, initialize<F>(k1));
00277 char k2[sizeof(F)];
00278 F* right = 0;
00279 assign(right, initialize<F>(k2));
00280 while (0 < len) {
00281 assign(half, len >> 1);
00282 assert(0 != middle);
00283 assign(*middle, b);
00284 instigate::stl::advance(*middle, half);
00285 if (invoke_predicate(c, const_dereference(*middle), v)) {
00286 assign(b, *middle);
00287 increment(b);
00288 assign(len, len - half - 1);
00289 } else {
00290 if (invoke_predicate(c, v, const_dereference(*middle))){
00291 assign(len, half);
00292 } else {
00293 assert(0 != left);
00294 assign(*left, instigate::stl::lower_bound(
00295 b, *middle, v));
00296 instigate::stl::advance(b, len);
00297 increment(*middle);
00298 assert(0 != right);
00299 assign(*right, instigate::stl::upper_bound(
00300 *middle, b, v));
00301 assign(p.first, *left);
00302 assign(p.second, *right);
00303 return;
00304 }
00305 }
00306 }
00307 assign(p.first, b);
00308 assign(p.second, b);
00309 }
00310
00311
00312
00313 #endif // INSTIGATE_STL_EQUAL_RANGE_HPP
00314