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_PARTIAL_SORT_COPY_HPP
00008 #define INSTIGATE_STL_PARTIAL_SORT_COPY_HPP
00009
00059
00060 #include "concept.hpp"
00061
00062
00063 #include <generic/base.hpp>
00064
00065
00066
00067
00068 namespace instigate {
00069 namespace stl {
00070 template <typename I, typename R>
00071 inline R partial_sort_copy(I b, I e, R f, R l);
00072
00073 template <typename I, typename R, typename BP>
00074 inline R partial_sort_copy(I b, I e, R f, R l, BP p);
00075 namespace implementation {
00076 template <typename I, typename R, typename D,
00077 typename Tp>
00078 inline R partial_sort_copy_aux(I b, I e, R f, R l, D*,
00079 Tp*);
00080 template <typename I, typename R, typename BP,
00081 typename D, typename Tp>
00082 inline R partial_sort_copy_aux(I b, I e, R f, R l,BP p,
00083 D*,Tp*);
00084 }
00085 }
00086 }
00087
00130 template <typename I, typename R>
00131 inline R instigate::stl::partial_sort_copy(I b, I e, R f, R l)
00132 {
00133 namespace SP = instigate::stl::single_pass_iterator;
00134 namespace RI = instigate::stl::readable_iterator;
00135 typedef typename RI::interface<I>::value_type value_type;
00136 typedef typename RI::interface<R>::value_type value_type2;
00137 CHECK_SAME_TYPE(value_type, value_type2);
00138 typedef typename SP::interface<R>::difference_type difference_type;
00139 value_type* vt = 0;
00140 difference_type* dt = 0;
00141 return implementation::partial_sort_copy_aux(b, e, f, l, dt, vt);
00142 }
00143
00145 template <typename I, typename R, typename D, typename Tp>
00146 inline R instigate::stl::implementation::partial_sort_copy_aux(I b, I e, R f,
00147 R l, D*, Tp*)
00148 {
00149 namespace RI = instigate::stl::readable_iterator;
00150 typedef typename RI::interface<I>::value_type value_type;
00151 if (equal(f, l)) {
00152 return l;
00153 }
00154 char k[sizeof(R)];
00155 R* real_last = 0;
00156 assign(real_last, copy_constructor(k, f));
00157 assert(0 != real_last);
00158 while(!equal(b, e) && !equal(*real_last, l)) {
00159 dereference_assign(*real_last, const_dereference(b));
00160 increment(*real_last);
00161 increment(b);
00162 }
00163 instigate::stl::make_heap(f, *real_last);
00164 while (!equal(b, e)) {
00165 if (equal(const_dereference(b), const_dereference(f))) {
00166 instigate::stl::implementation::adjust_heap_aux(f, D(0),
00167 D(*real_last - f),
00168 Tp(const_dereference(b)));
00169 }
00170 increment(b);
00171 }
00172 instigate::stl::sort_heap(f, *real_last);
00173 return *real_last;
00174 }
00175
00212 template <typename I, typename R, typename BP>
00213 inline R instigate::stl::partial_sort_copy(I b, I e, R f, R l, BP p)
00214 {
00215 namespace RA = instigate::stl::random_access_iterator;
00216 namespace SP = instigate::stl::single_pass_iterator;
00217 namespace WR = instigate::stl::writable_iterator;
00218 namespace RI = instigate::stl::readable_iterator;
00219 namespace EQ = instigate::generic::equality_comparable;
00220 namespace LT = instigate::generic::less_than_comparable;
00221 namespace BPI = instigate::stl::binary_predicate;
00222 typedef typename RI::interface<R>::value_type value_type;
00223 typedef typename SP::interface<R>::difference_type difference_type;
00224 CHECK(RA::requirements<R>);
00225 CHECK(WR::requirements<R>);
00226 CHECK(BPI::requirements<BP>);
00227 CHECK(LT::requirements<value_type>);
00228 value_type* vt = 0;
00229 difference_type* dt = 0;
00230 return implementation::partial_sort_copy_aux(b, e, f, l, p, dt, vt);
00231 }
00232
00234 template <typename I, typename R, typename BP, typename D, typename Tp>
00235 inline R instigate::stl::implementation::partial_sort_copy_aux(I b, I e, R f,
00236 R l, BP p, D*, Tp*)
00237 {
00238 namespace DF = instigate::generic::default_constructible;
00239 namespace RA = instigate::stl::random_access_iterator;
00240 namespace RI = instigate::stl::readable_iterator;
00241 typedef typename RI::interface<I>::value_type value_type;
00242 typedef typename RI::interface<R>::value_type value_type2;
00243 CHECK_SAME_TYPE(value_type, value_type2);
00244 if (equal(f, l)) {
00245 return l;
00246 }
00247 char k[sizeof(R)];
00248 R* real_last = 0;
00249 assign(real_last, copy_constructor(k, f));
00250 assert(0 != real_last);
00251 while(!equal(b, e) && !equal(*real_last, l)) {
00252 dereference_assign((*real_last), const_dereference(b));
00253 increment(*real_last);
00254 increment(b);
00255 }
00256 instigate::stl::make_heap(f, *real_last, p);
00257 while (!equal(b, e)) {
00258 if (invoke_predicate(p, const_dereference(b),
00259 const_dereference(f)))
00260 {
00261 instigate::stl::implementation::adjust_heap_aux(
00262 f, D(0), D(*real_last - f),
00263 const_dereference(b), p);
00264 }
00265 increment(b);
00266 }
00267 instigate::stl::sort_heap(f, *real_last, p);
00268 return *real_last;
00269 }
00270
00271
00272
00273 #endif // INSTIGATE_STL_PARTIAL_SORT_HPP