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_UNIQUE_COPY_HPP
00008 #define INSTIGATE_STL_UNIQUE_COPY_HPP
00009
00059
00060 #include "concept.hpp"
00061 #include "_adjacent_find.hpp"
00062
00063
00064
00065
00066
00067
00068 namespace instigate {
00069 namespace stl {
00070 template <typename I, typename O>
00071 O unique_copy(I b, I e, O r);
00072
00073 template <typename I, typename O, typename BP>
00074 O unique_copy(I b, I e, O r, BP p);
00075
00076 namespace implementation {
00077 template <typename I, typename O>
00078 O unique_copy_aux(I b, I e, O r,
00079 instigate::stl::forward_iterator::tag);
00080
00081 template <typename I, typename O>
00082 O unique_copy_aux(I b, I e, O r,
00083 instigate::stl::incrementable_iterator::tag);
00084
00085 template <typename I, typename O, typename Tp>
00086 O unique_copy_aux(I b, I e, O r, Tp*);
00087
00088 template <typename I, typename O, typename BP>
00089 O unique_copy_aux(I b, I e, O r, BP p,
00090 instigate::stl::forward_iterator::tag);
00091
00092 template <typename I, typename O, typename BP>
00093 O unique_copy_aux(I b, I e, O r, BP p,
00094 instigate::stl::incrementable_iterator::tag);
00095
00096 template <typename I, typename O, typename BP,
00097 typename Tp>
00098 O unique_copy_aux(I b, I e, O r, BP p, Tp*);
00099 }
00100 }
00101 }
00102
00144 template <typename I, typename O>
00145 O instigate::stl::unique_copy(I b, I e, O r)
00146 {
00147 namespace SP = instigate::stl::forward_iterator;
00148 namespace RI = instigate::stl::readable_iterator;
00149 namespace WR = instigate::stl::writable_iterator;
00150 namespace INC = instigate::stl::incrementable_iterator;
00151 namespace EQ = instigate::generic::equality_comparable;
00152 typedef typename RI::interface<I>::value_type value_type;
00153 CHECK(SP::requirements<I>);
00154 CHECK(RI::requirements<I>);
00155 CHECK(WR::requirements<O>);
00156 CHECK(INC::requirements<O>);
00157 CHECK(EQ::requirements<value_type>);
00158 if(equal(b, e)){
00159 return r;
00160 }
00161 typename instigate::stl::incrementable_iterator::interface<O>::
00162 iterator_category category;
00163 return implementation::unique_copy_aux(b, e, r, category);
00164 }
00165
00170 template <typename I, typename O, typename Tp>
00171 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r, Tp*)
00172 {
00173 namespace WI = instigate::stl::writable_iterator;
00174 namespace RI = instigate::stl::readable_iterator;
00175 namespace EQ = instigate::generic::equality_comparable;
00176 namespace SP = instigate::stl::single_pass_iterator;
00177 namespace INC = instigate::stl::incrementable_iterator;
00178 Tp value;
00179 assign(value, const_dereference(b));
00180 dereference_assign(r, value);
00181 increment(b);
00182 while (!equal(b, e)) {
00183 if (!equal(value, const_dereference(b))) {
00184 assign(value, const_dereference(b));
00185 increment(r);
00186 dereference_assign(r, value);
00187 }
00188 increment(b);
00189 }
00190 increment(r);
00191 return r;
00192 }
00193
00199 template <typename I, typename O>
00200 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r,
00201 instigate::stl::incrementable_iterator::tag)
00202 {
00203 namespace WI = instigate::stl::writable_iterator;
00204 typedef typename WI::interface<I>::value_type value_type;
00205 return unique_copy_aux(b, e, r, value_type());
00206 }
00207
00213 template <typename I, typename O>
00214 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r,
00215 instigate::stl::forward_iterator::tag)
00216 {
00217 namespace WI = instigate::stl::writable_iterator;
00218 namespace RI = instigate::stl::readable_iterator;
00219 namespace EQ = instigate::generic::equality_comparable;
00220 namespace SP = instigate::stl::single_pass_iterator;
00221 namespace INC = instigate::stl::incrementable_iterator;
00222 typedef typename RI::interface<O>::value_type value_type;
00223 dereference_assign(r, const_dereference(b));
00224 increment(b);
00225 while (!equal(b, e)){
00226 if (!equal(const_dereference(r), const_dereference(b))) {
00227 increment(r);
00228 dereference_assign(r, const_dereference(b));
00229 }
00230 increment(b);
00231 }
00232 increment(r);
00233 return r;
00234 }
00235
00240 template <typename I, typename O, typename BP, typename Tp>
00241 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r, BP p, Tp*)
00242 {
00243 namespace WI = instigate::stl::writable_iterator;
00244 namespace RI = instigate::stl::readable_iterator;
00245 namespace EQ = instigate::generic::equality_comparable;
00246 namespace SP = instigate::stl::single_pass_iterator;
00247 namespace INC = instigate::stl::incrementable_iterator;
00248 namespace BPI = instigate::stl::binary_predicate;
00249 Tp value;
00250 assign(value, const_dereference(b));
00251 dereference_assign(r, value);
00252 increment(b);
00253 while (!equal(b, e)) {
00254 if (!invoke_predicate(value, const_dereference(b))) {
00255 assign(value, const_dereference(b));
00256 increment(r);
00257 dereference_assign(r, value);
00258 }
00259 increment(b);
00260 }
00261 increment(r);
00262 return r;
00263 }
00264
00270 template <typename I, typename O, typename BP>
00271 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r, BP p,
00272 instigate::stl::incrementable_iterator::tag)
00273 {
00274 namespace RI = instigate::stl::readable_iterator;
00275 typedef typename RI::interface<I>::value_type value_type;
00276 return unique_copy_aux(b, e, r, p, value_type());
00277 }
00278
00284 template <typename I, typename O, typename BP>
00285 O instigate::stl::implementation::unique_copy_aux(I b, I e, O r, BP p,
00286 instigate::stl::forward_iterator::tag)
00287 {
00288 namespace BI = instigate::stl::binary_predicate;
00289 namespace INC = instigate::stl::incrementable_iterator;
00290 namespace WI = instigate::stl::writable_iterator;
00291 namespace RI = instigate::stl::readable_iterator;
00292 namespace EQ = instigate::generic::equality_comparable;
00293 dereference_assign(r, const_dereference(b));
00294 increment(b);
00295 while (!equal(b, e)) {
00296 if (!invoke_predicate(p, const_dereference(r),
00297 const_dereference(b)))
00298 {
00299 increment(r);
00300 dereference_assign(r, const_dereference(b));
00301 }
00302 increment(b);
00303 }
00304 increment(r);
00305 return r;
00306 }
00307
00347 template <typename I, typename O, typename BP>
00348 O instigate::stl::unique_copy(I b, I e, O r, BP p)
00349 {
00350 namespace SP = instigate::stl::forward_iterator;
00351 namespace RI = instigate::stl::readable_iterator;
00352 namespace WR = instigate::stl::writable_iterator;
00353 namespace INC = instigate::stl::incrementable_iterator;
00354 namespace EQ = instigate::generic::equality_comparable;
00355 namespace BI = instigate::stl::binary_predicate;
00356 typedef typename RI::interface<I>::value_type value_type;
00357 CHECK(SP::requirements<I>);
00358 CHECK(RI::requirements<I>);
00359 CHECK(WR::requirements<O>);
00360 CHECK(INC::requirements<O>);
00361 CHECK(BI::requirements<BP>);
00362 CHECK(EQ::requirements<value_type>);
00363 if(equal(b, e)){
00364 return r;
00365 }
00366 typename instigate::stl::incrementable_iterator::interface<O>::
00367 iterator_category category;
00368 return implementation::unique_copy_aux(b, e, r, p, category);
00369 }
00370
00371
00372
00373 #endif // INSTIGATE_STL_UNIQUE_COPY_HPP
00374