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_ADJACENT_DIFFERENCE_HPP
00008 #define INSTIGATE_STL_ADJACENT_DIFFERENCE_HPP
00009
00058
00059 #include "concept.hpp"
00060 #include "_basis.hpp"
00061
00062
00063
00064
00065
00066
00067 namespace instigate {
00068 namespace stl {
00069 namespace implementation {
00070 template <typename F, typename O, typename T>
00071 O adjacent_difference_aux(F b, F e, O r, T*);
00072 template <typename F, typename O, typename T,
00073 typename BF>
00074 O adjacent_difference_aux(F b, F e, O r, T*, BF f);
00075 }
00076 template <typename F, typename O>
00077 O adjacent_difference(F b, F e, O r);
00078 template <typename F, typename O, typename BF>
00079 O adjacent_difference(F b, F e, O r, BF f);
00080 }
00081 }
00082
00118 template <typename F, typename O>
00119 O instigate::stl::adjacent_difference(F b, F e, O r)
00120 {
00121 namespace FI = instigate::stl::forward_iterator;
00122 namespace RI = instigate::stl::readable_iterator;
00123 namespace INC = instigate::stl::incrementable_iterator;
00124 namespace WR = instigate::stl::writable_iterator;
00125 CHECK(FI::requirements<F>);
00126 CHECK(RI::requirements<F>);
00127 CHECK(INC::requirements<O>);
00128 CHECK(WR::requirements<O>);
00129 typedef typename RI::interface<F>::value_type value_type;
00130 CHECK_CONVERTIBILITY(value_type, typename WR::interface<O>::value_type);
00131 if (equal(b, e)) {
00132 return r;
00133 }
00134 dereference_assign(r, const_dereference(b));
00135 value_type* k = 0;
00136 return instigate::stl::implementation::
00137 adjacent_difference_aux(b, e, r, k);
00138 }
00139
00141 template <typename F, typename O, typename T>
00142 O instigate::stl::implementation::adjacent_difference_aux(F b, F e, O r, T*)
00143 {
00144 T v;
00145 assign(v, const_dereference(b));
00146 increment(b);
00147 while (!equal(b, e)) {
00148 T t;
00149 assign(t, const_dereference(b));
00150 increment(r);
00151 dereference_assign(r, t - v);
00152 assign(v, t);
00153 increment(b);
00154 }
00155 increment(r);
00156 return r;
00157 }
00158
00210 template <typename F, typename O, typename BF>
00211 O instigate::stl::adjacent_difference(F b, F e, O r, BF f)
00212 {
00213 namespace FI = instigate::stl::forward_iterator;
00214 namespace RI = instigate::stl::readable_iterator;
00215 namespace INC = instigate::stl::incrementable_iterator;
00216 namespace WR = instigate::stl::writable_iterator;
00217 namespace BFI = instigate::stl::binary_function;
00218 CHECK(FI::requirements<F>);
00219 CHECK(RI::requirements<F>);
00220 CHECK(INC::requirements<O>);
00221 CHECK(WR::requirements<O>);
00222 typedef typename RI::interface<F>::value_type value_type1;
00223 typedef typename BFI::interface<BF>::first_argument_type
00224 first_argument_type;
00225 typedef typename BFI::interface<BF>::second_argument_type
00226 second_argument_type;
00227 typedef typename WR::interface<O>::value_type value_type2;
00228 typedef typename BFI::interface<BF>::result_type result_type;
00229 CHECK_CONVERTIBILITY(value_type1, first_argument_type);
00230 CHECK_CONVERTIBILITY(value_type1, second_argument_type);
00231 CHECK_CONVERTIBILITY(value_type1, value_type2);
00232 CHECK_CONVERTIBILITY(result_type, value_type2);
00233 if (equal(b, e)) {
00234 return r;
00235 }
00236 dereference_assign(r, const_dereference(b));
00237 value_type1* k = 0;
00238 return instigate::stl::implementation::
00239 adjacent_difference_aux(b, e, r, k, f);
00240 }
00241
00243 template <typename F, typename O, typename T, typename BF>
00244 O instigate::stl::implementation::
00245 adjacent_difference_aux(F b, F e, O r, T*, BF f)
00246 {
00247 T v;
00248 assign(v, const_dereference(b));
00249 increment(b);
00250 while (!equal(b, e)) {
00251 T t;
00252 assign(t, const_dereference(b));
00253 increment(r);
00254 dereference_assign(r, invoke(f, t, v));
00255 assign(v, t);
00256 increment(b);
00257 }
00258 increment(r);
00259 return r;
00260 }
00261
00262
00263
00264 #endif // INSTIGATE_STL_ADJACENT_DIFFERENCE_HPP