00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _ARAGELI_UTILS_iteradapt_hpp_
00014 #define _ARAGELI_UTILS_iteradapt_hpp_
00015
00016 #include "config.hpp"
00017
00018 #include <iterator>
00019
00020
00021 namespace Arageli
00022 {
00023
00024
00025
00026
00027
00028 template <typename T, typename TB, typename F>
00029 class apply_iterator :
00030 public std::iterator
00031 <
00032 typename std::iterator_traits<TB>::iterator_category,
00033 T,
00034 typename std::iterator_traits<TB>::difference_type,
00035 T*,
00036 T&
00037 >
00038 {
00039 typedef std::iterator_traits<TB> Iterbase;
00040
00041 template <typename T1, typename TB1, typename F1>
00042 friend class apply_iterator;
00043
00044 public:
00045
00046 typedef TB base_iterator;
00047 typedef F function;
00048
00049 apply_iterator () {}
00050
00051 template <typename T1, typename TB1, typename F1>
00052 apply_iterator (const apply_iterator<T1, TB1, F1>& x)
00053 : fu(x.fu), iter(x.iter) {}
00054
00055 explicit apply_iterator (const base_iterator& iter_a, const function& fu_a = function())
00056 : iter(iter_a), fu(fu_a) {}
00057
00058 explicit apply_iterator (const function& fu_a) : fu(fu_a) {}
00059
00060 const base_iterator& base () const { return iter; }
00061 base_iterator& base () { return iter; }
00062 const function& adapter () const { return fu; }
00063 function& adapter () { return fu; }
00064
00065 T* operator-> () const { return &fu(*iter); }
00066 T& operator* () const { return fu(*iter); }
00067
00068 apply_iterator& operator++ () { ++iter; return *this; }
00069 apply_iterator& operator-- () { --iter; return *this; }
00070
00071 apply_iterator operator++ (int)
00072 {
00073 apply_iterator t = *this;
00074 operator++();
00075 return t;
00076 }
00077
00078 apply_iterator operator-- (int)
00079 {
00080 apply_iterator t = *this;
00081 operator--();
00082 return t;
00083 }
00084
00085 apply_iterator& operator+= (typename Iterbase::difference_type n)
00086 { iter += n; return *this; }
00087
00088 apply_iterator& operator-= (typename Iterbase::difference_type n)
00089 { iter += n; return *this; }
00090
00091 T& operator[] (typename Iterbase::difference_type n) const
00092 { return fu(iter[n]); }
00093
00094 private:
00095
00096 function fu;
00097 base_iterator iter;
00098
00099 };
00100
00101
00102 template <typename T, typename TB, typename F>
00103 apply_iterator<T, TB, F> operator+
00104 (apply_iterator<T, TB, F> x, typename apply_iterator<T, TB, F>::difference_type n)
00105 { return x += n; }
00106
00107
00108 template <typename T, typename TB, typename F>
00109 apply_iterator<T, TB, F> operator-
00110 (apply_iterator<T, TB, F> x, typename apply_iterator<T, TB, F>::difference_type n)
00111 { return x -= n; }
00112
00113
00114 template <typename T, typename TB, typename F>
00115 inline typename std::iterator_traits<TB>::difference_type operator-
00116 (const apply_iterator<T, TB, F>& a, const apply_iterator<T, TB, F>& b)
00117 { return a.base() - b.base(); }
00118
00119
00120 #define _ARAGELI_ITERADAPT_CMP_OPER(OPER) \
00121 template <typename T, typename TB, typename F> \
00122 inline bool operator OPER \
00123 ( \
00124 const apply_iterator<T, TB, F>& a, \
00125 const apply_iterator<T, TB, F>& b \
00126 ) \
00127 { return a.base() OPER b.base(); }
00128
00129
00130 _ARAGELI_ITERADAPT_CMP_OPER(==)
00131 _ARAGELI_ITERADAPT_CMP_OPER(!=)
00132 _ARAGELI_ITERADAPT_CMP_OPER(<)
00133 _ARAGELI_ITERADAPT_CMP_OPER(>)
00134 _ARAGELI_ITERADAPT_CMP_OPER(<=)
00135 _ARAGELI_ITERADAPT_CMP_OPER(>=)
00136
00137
00138
00139
00140 template <typename T1, typename T2>
00141 struct Min_iterator_traits;
00142
00143
00144
00145
00146
00147
00148
00149 template <typename T, typename TB1, typename TB2, typename F>
00150 class Iterpair :
00151 public std::iterator
00152 <
00153
00154 typename std::iterator_traits<TB1>::iterator_category,
00155 T,
00156
00157 typename std::iterator_traits<TB1>::difference_type,
00158 T*,
00159 T&
00160 >
00161 {
00162
00163 typedef std::iterator_traits<TB1> Iterbase;
00164
00165 public:
00166
00167 typedef TB1 Base_first;
00168 typedef TB2 Base_second;
00169 typedef F function;
00170
00171 Iterpair () {}
00172 Iterpair
00173 (
00174 const Base_first& iterf_a,
00175 const Base_second& iters_a,
00176 const function& fu_a = function()
00177 )
00178 : iterf(iterf_a),
00179 iters(iters_a),
00180 fu(fu_a)
00181 {}
00182
00183 Iterpair (const function& fu_a) : fu(fu_a) {}
00184
00185 const Base_first& base_first () const { return iterf; }
00186 Base_first& base_first () { return iterf; }
00187 const Base_second& base_second () const { return iters; }
00188 Base_second& base_second () { return iters; }
00189
00190
00191 const function& unitor () const { return fu; }
00192 function& unitor () { return fu; }
00193
00194 T* operator-> () const { return &fu(*iterf, *iters); }
00195 typename F::result_type operator* () const { return fu(*iterf, *iters); }
00196
00197 Iterpair& operator++ () { ++iterf; ++iters; return *this; }
00198 Iterpair& operator-- () { --iterf; --iters; return *this; }
00199
00200 Iterpair& operator+= (typename Iterbase::difference_type n)
00201 { iterf += n; iters += n; return *this; }
00202
00203 Iterpair& operator-= (typename Iterbase::difference_type n)
00204 { iterf += n; iters += n; return *this; }
00205
00206 typename F::result_type operator[] (typename Iterbase::difference_type n) const
00207 { return fu(iterf[n], iters[n]); }
00208
00209 Iterpair operator+ (typename Iterbase::difference_type n)
00210 { return Iterpair(iterf + n, iters + n, fu); }
00211
00212 Iterpair operator- (typename Iterbase::difference_type n)
00213 { return Iterpair(iterf - n, iters - n, fu); }
00214
00215 private:
00216
00217 function fu;
00218 Base_first iterf;
00219 Base_second iters;
00220
00221 };
00222
00223
00224 template <typename T, typename TB1, typename TB2, typename F>
00225 inline typename std::iterator_traits<TB1>::difference_type operator-
00226 (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00227 { return a.base_first() - b.base_first(); }
00228
00229
00230 template <typename T, typename TB1, typename TB2, typename F>
00231 inline bool operator== (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00232 { return a.base_first() == b.base_first(); }
00233
00234 template <typename T, typename TB1, typename TB2, typename F>
00235 inline bool operator!= (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00236 { return a.base_first() != b.base_first(); }
00237
00238 template <typename T, typename TB1, typename TB2, typename F>
00239 inline bool operator< (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00240 { return a.base_first() < b.base_first(); }
00241
00242 template <typename T, typename TB1, typename TB2, typename F>
00243 inline bool operator> (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00244 { return a.base_first() > b.base_first(); }
00245
00246 template <typename T, typename TB1, typename TB2, typename F>
00247 inline bool operator<= (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00248 { return a.base_first() == b.base_first(); }
00249
00250 template <typename T, typename TB1, typename TB2, typename F>
00251 inline bool operator>= (const Iterpair<T, TB1, TB2, F>& a, const Iterpair<T, TB1, TB2, F>& b)
00252 { return a.base_first() >= b.base_first(); }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 }
00277
00278
00279 #endif // #ifndef _ARAGELI_UTILS_iteradapt_hpp_