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_PUSH_HEAP_HPP
00008 #define INSTIGATE_STL_PUSH_HEAP_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_basis.hpp"
00062
00063
00064 #include <generic/base.hpp>
00065
00066
00067
00068
00069 namespace instigate {
00070 namespace stl {
00071 template <typename I>
00072 void push_heap(I, I);
00073
00074 template <typename I, typename C>
00075 void push_heap(I, I, C);
00076
00077 namespace implementation {
00078 template <typename I, typename D, typename T>
00079 void push_heap_aux(I , D , D, T);
00080
00081 template <typename I, typename D, typename T,typename C>
00082 void push_heap_aux(I, D, D, T, C);
00083 }
00084 }
00085 }
00086
00113 template <typename I>
00114 void instigate::stl::push_heap(I b, I e)
00115 {
00116 typedef typename stl::random_access_iterator::interface<I>::
00117 difference_type D;
00118 typedef typename stl::readable_iterator::interface<I>::value_type T;
00119 CHECK(instigate::stl::random_access_iterator::requirements<I>);
00120 CHECK(instigate::stl::lvalue_iterator::requirements<I>);
00121 CHECK(instigate::generic::less_than_comparable::requirements<T>);
00122 D a = stl::distance(b, e) - 1;
00123 D k = 0;
00124 char buf[sizeof(I)];
00125 I* p = 0;
00126 assign(p, copy_constructor(buf, e));
00127 assert(0 != p);
00128 stl::advance(*p, -1);
00129 T t = dereference(*p);
00130 implementation::push_heap_aux(b, a, k, t);
00131 }
00132
00160 template <typename I, typename C>
00161 void instigate::stl::push_heap(I b, I e, C c)
00162 {
00163 typedef typename stl::readable_iterator::interface<I>::value_type T;
00164 typedef typename stl::random_access_iterator::interface<I>::
00165 difference_type D;
00166 CHECK(stl::random_access_iterator::requirements<I>);
00167 CHECK(stl::lvalue_iterator::requirements<I>);
00168 CHECK(stl::binary_predicate::requirements<C>);
00169 CHECK(instigate::generic::less_than_comparable::requirements<T>);
00170 D a = 0;
00171 D k = stl::distance(b, e) - 1;
00172 char buf[sizeof(I)];
00173 I* p = 0;
00174 assign(p, copy_constructor(buf, e));
00175 assert(0 != p);
00176 stl::advance(*p, -1);
00177 T o = const_dereference(*p);
00178 implementation::push_heap_aux(b, k, a, o, c);
00179 }
00180
00182 template <typename I, typename D, typename T>
00183 void instigate::stl::implementation::push_heap_aux(I b, D h, D t, T v)
00184 {
00185 D p = (h - 1) / 2;
00186 char buf[sizeof(I)];
00187 I* z = 0;
00188 assign(z, copy_constructor(buf, b));
00189 assert(0 != z);
00190 stl::advance(*z, p);
00191 char buf1[sizeof(I)];
00192 I* z1 = 0;
00193 assign(z1, copy_constructor(buf1, b));
00194 while (less_than(t, h) && less_than(const_dereference(*z), v))
00195 {
00196 assign(*z, b);
00197 stl::advance(*z, h);
00198 assert(0 != z1);
00199 assign(*z1, b);
00200 stl::advance(*z1, p);
00201 dereference_assign((*z), const_dereference(*z1));
00202 assign(h, p);
00203 assign(p, (h - 1) / 2);
00204 assign(*z, b);
00205 stl::advance(*z, p);
00206 }
00207 assign(*z, b);
00208 stl::advance(*z, h);
00209 dereference_assign((*z), v);
00210 }
00211
00213 template <typename I, typename D, typename T, typename C>
00214 void instigate::stl::implementation::push_heap_aux(I b , D h, D t, T v, C c)
00215 {
00216 D p = (h - 1) / 2;
00217 char buf[sizeof(I)];
00218 I* z = 0;
00219 assign(z, copy_constructor(buf, b));
00220 assert(0 != z);
00221 stl::advance(*z, p);
00222 char buf1[sizeof(I)];
00223 I* z1 = 0;
00224 assign(z1, copy_constructor(buf1, b));
00225 while (less_than(t, h) && invoke_predicate(c, const_dereference(*z),v))
00226 {
00227 assign(*z, b);
00228 stl::advance(*z, h);
00229 assert(0 != z1);
00230 assign(*z1, b);
00231 stl::advance(*z1, p);
00232 dereference_assign((*z), const_dereference(*z1));
00233 assign(h, p);
00234 assign(p, (h - 1) / 2);
00235 assign(*z, b);
00236 stl::advance(*z, p);
00237 }
00238 assign(*z, b);
00239 stl::advance(*z, h);
00240 dereference_assign((*z), v);
00241 }
00242
00243
00244
00245 #endif // INSTIGATE_STL_PUSH_HEAP_HPP