iteradapt.hpp

Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003     iteradapt.hpp -- Iterator utilities declaration and implementation.
00004 
00005     WARNING. Implementation of 'Iterpair' is temporary limited.
00006 
00007     Copyright (C) Sergey S. Lyalin, 2005
00008 
00009     16.04.2005
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 // Iterator adapter with base iterator type TB and adaptation functor type F
00026 // Functor F must operate with reference on base element type of base iterator.
00027 // T -- is value type for new iterator type
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 // Iterator pair incapsulates two iterators and represented virtual sequence as
00145 // element sequence generated by functor F object. Suppose TB2 iterator is
00146 // more 'flexible' iterator then TB1 iterator. That's if some operation is applicable
00147 // for type TB1 then one is applicable for type TB2. This nonsymmetrical situation is
00148 // temporary.
00149 template <typename T, typename TB1, typename TB2, typename F>
00150 class Iterpair :
00151     public std::iterator
00152     <
00153         //typename Min_iterator_traits<TB1, TB2>::iterator_category,
00154         typename std::iterator_traits<TB1>::iterator_category,
00155         T,
00156         //typename Min_iterator_traits<TB1, TB2>::difference_type,
00157         typename std::iterator_traits<TB1>::difference_type,
00158         T*,
00159         T&
00160     >
00161 {
00162     //typedef Min_iterator_traits<TB1, TB2> Iterbase;
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; // REMARK: may be some other name is better for this type
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     // WARNING! Why name is `unitor'? Recall the renaming history.
00191     const function& unitor () const { return fu; }
00192     function& unitor () { return fu; }
00193 
00194     T* operator-> () const { return &fu(*iterf, *iters); }  // may be problems
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 //template <typename Iter_base>
00258 //class slice_iterator :
00259 //  public std::iterator
00260 //  <
00261 //      typename std::iterator_traits<Iter_base>::iterator_category,
00262 //      typename std::iterator_traits<Iter_base>::value_type,
00263 //      typename std::iterator_traits<Iter_base>::difference_type,
00264 //      typename std::iterator_traits<Iter_base>::pointer,
00265 //      typename std::iterator_traits<Iter_base>::reference
00266 //  >
00267 //{
00268 //public:
00269 //  typedef typename std::iterator_traits<Iter_base>::value_type value_type;
00270 //  typedef typename std::iterator_traits<Iter_base>::value_type difference_type;
00271 //
00272 //
00273 //};
00274 
00275 
00276 } // namespace Arageli
00277 
00278 
00279 #endif // #ifndef _ARAGELI_UTILS_iteradapt_hpp_

Generated on Thu Aug 31 17:38:07 2006 for Arageli by  doxygen 1.4.7