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_POP_HEAP_HPP
00008 #define INSTIGATE_STL_POP_HEAP_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_basis.hpp"
00062 #include "_push_heap.hpp"
00063 #include "_iter_swap.hpp"
00064
00065
00066 #include <generic/base.hpp>
00067
00068
00069
00070
00071 namespace instigate {
00072 namespace stl {
00073 template <typename I>
00074 void pop_heap(I, I);
00075
00076 template <typename I, typename C>
00077 void pop_heap(I, I, C);
00078
00085 namespace implementation {
00086 template <typename I, typename D, typename T>
00087 void adjust_heap_aux(I, D, D, T);
00088
00089 template <typename I, typename D, typename T,typename C>
00090 void adjust_heap_aux(I, D, D, T, C);
00091
00092 template <typename I, typename T>
00093 void pop_heap_aux(I, I, I, T);
00094
00095 template <typename I, typename T, typename C>
00096 void pop_heap_aux(I, I, I, T, C);
00097 }
00098
00099 }
00100 }
00101
00128 template <typename I>
00129 void instigate::stl::pop_heap(I b, I e)
00130 {
00131 char buf[sizeof(I)];
00132 I* buf_p = 0;
00133 typedef typename stl::readable_iterator::interface<I>::value_type Tp;
00134 CHECK(stl::random_access_iterator::requirements<I>);
00135 CHECK(stl::lvalue_iterator::requirements<I>);
00136 CHECK(instigate::generic::less_than_comparable::requirements<Tp>);
00137 assign(buf_p, copy_constructor(buf, e));
00138 stl::advance(*buf_p, -1);
00139 implementation::pop_heap_aux(b, *buf_p, *buf_p, dereference(*buf_p));
00140 }
00141
00146 template <typename I, typename T>
00147 void instigate::stl::implementation::pop_heap_aux(I b, I e, I r, T v)
00148 {
00149 typedef typename stl::random_access_iterator::interface<I>::
00150 difference_type D;
00151 stl::iter_swap(r, b);
00152 D a = 0;
00153 D k = stl::distance(b, e);
00154 implementation::adjust_heap_aux(b, a, k, v);
00155 }
00156
00161 template <typename I, typename D, typename T>
00162 void instigate::stl::implementation::adjust_heap_aux(I b, D holeIndex, D len,
00163 T value)
00164 {
00165 D topIndex;
00166 assign(topIndex, holeIndex);
00167 D secondChild;
00168 assign(secondChild, 2 * holeIndex + 2);
00169 char buf[sizeof(I)];
00170 I* buf_p = 0;
00171 assign(buf_p, initialize<I>(buf));
00172 char buf1[sizeof(I)];
00173 I* buf_p1 = 0;
00174 assign(buf_p1, initialize<I>(buf1));
00175 while (less_than(secondChild, len)) {
00176 assert(0 != buf_p);
00177 assign(*buf_p, b);
00178 stl::advance(*buf_p, secondChild);
00179 assert(0 != buf_p1);
00180 assign(*buf_p1, b);
00181 stl::advance(*buf_p1, secondChild - 1);
00182 if (less_than(const_dereference(*buf_p),
00183 const_dereference(*buf_p1)))
00184 {
00185 --secondChild;
00186 }
00187 assign(*buf_p, b);
00188 stl::advance(*buf_p, holeIndex);
00189 assign(*buf_p1, b);
00190 stl::advance(*buf_p1, secondChild);
00191 stl::iter_swap(*buf_p, *buf_p1);
00192 assign(holeIndex, secondChild);
00193 assign(secondChild, 2 * (secondChild + 1));
00194 }
00195 if (equal(secondChild, len)) {
00196 assert(0 != buf_p);
00197 assign(*buf_p, b);
00198 stl::advance(*buf_p, holeIndex);
00199 assert(0 != buf_p1);
00200 assign(*buf_p1, b);
00201 stl::advance(*buf_p1, secondChild - 1);
00202 stl::iter_swap(*buf_p, *buf_p1);
00203 assign(holeIndex, secondChild - 1);
00204 }
00205 implementation::push_heap_aux(b, holeIndex, topIndex, value);
00206 }
00207
00235 template <typename I, typename C>
00236 void instigate::stl::pop_heap(I b, I e, C c)
00237 {
00238 CHECK(instigate::stl::random_access_iterator::requirements<I>);
00239 CHECK(instigate::stl::lvalue_iterator::requirements<I>);
00240 char buf[sizeof(I)];
00241 I* buf_p = 0;
00242 assign(buf_p, copy_constructor(buf, e));
00243 assert(0 != buf_p);
00244 stl::advance(*buf_p, -1);
00245 implementation::pop_heap_aux(b, *buf_p, *buf_p, dereference(*buf_p), c);
00246 }
00247
00252 template <typename I, typename T, typename C>
00253 void instigate::stl::implementation::pop_heap_aux(I b, I e, I r, T v, C c)
00254 {
00255 typedef typename stl::random_access_iterator::interface<I>::
00256 difference_type D;
00257 stl::iter_swap(r, b);
00258 D a = 0;
00259 D k = stl::distance(b, e);
00260 implementation::adjust_heap_aux(b, a, k, v, c);
00261 }
00262
00267 template <typename I, typename D, typename T, typename C>
00268 void instigate::stl::implementation::adjust_heap_aux(I b, D h,D l, T v, C c)
00269 {
00270 D t;
00271 assign(t, h);
00272 D secondChild;
00273 assign(secondChild, 2 * h + 2);
00274 char buf[sizeof(I)];
00275 I* buf_p = 0;
00276 assign(buf_p, initialize<I>(buf));
00277 char buf1[sizeof(I)];
00278 I* buf_p1 = 0;
00279 assign(buf_p1, initialize<I>(buf1));
00280 while (less_than(secondChild, l)) {
00281 assert(0 != buf_p);
00282 assign(*buf_p, b);
00283 stl::advance(*buf_p, secondChild);
00284 assign(*buf_p1, b);
00285 assert(0 != buf_p1);
00286 stl::advance(*buf_p1, secondChild - 1);
00287 if (invoke_predicate(c, dereference(*buf_p),
00288 dereference(*buf_p1)))
00289 {
00290 --secondChild;
00291 }
00292 assign(*buf_p, b);
00293 stl::advance(*buf_p, h);
00294 assign(*buf_p1, b);
00295 stl::advance(*buf_p1, secondChild);
00296 stl::iter_swap(*buf_p, *buf_p1);
00297 assign(h, secondChild);
00298 assign(secondChild, 2 * (secondChild + 1));
00299 }
00300 if (equal(secondChild, l)) {
00301 assert(0 != buf_p);
00302 assign(*buf_p, b);
00303 stl::advance(*buf_p, h);
00304 assign(*buf_p1, b);
00305 assert(0 != buf_p1);
00306 stl::advance(*buf_p1, secondChild - 1);
00307 stl::iter_swap(*buf_p, *buf_p1);
00308 assign(h, secondChild - 1);
00309 }
00310 implementation::push_heap_aux(b, h, t, v, c);
00311 }
00312
00313
00314
00315
00316 #endif // INSTIGATE_STL_POP_HEAP_HPP