00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef MORE_GEN_ITERATOR_COMPOSITION_H
00030 #define MORE_GEN_ITERATOR_COMPOSITION_H
00031
00032 #include <more/meta.h>
00033 #include <iterator>
00034
00035 namespace more {
00036 namespace gen {
00037
00038 template<typename C1, typename C2>
00039 struct iterator_category_intersection_
00040 {
00041 typedef list_< std::input_iterator_tag,
00042 std::forward_iterator_tag,
00043 std::bidirectional_iterator_tag,
00044 std::random_access_iterator_tag >::eval ordering;
00045 private:
00046 typedef typename order_<C1, C2, ordering>::eval ordered;
00047 public:
00048 typedef typename ordered::first_type eval;
00049 };
00050
00051
00052
00053 template<typename Iterator1, typename Iterator2, typename BinaryFunction>
00054 struct iterator_composition {
00055 typedef iterator_composition self;
00056 typedef typename iterator_category_intersection_
00057 < typename std::iterator_traits<Iterator1>::iterator_category,
00058 typename std::iterator_traits<Iterator2>::iterator_category
00059 >::eval iterator_category;
00060 typedef typename BinaryFunction::result_type value_type;
00061 typedef typename std::iterator_traits<Iterator1>::difference_type
00062 difference_type;
00063 typedef typename std::iterator_traits<Iterator1>::pointer pointer;
00064 typedef typename std::iterator_traits<Iterator1>::reference
00065 reference;
00066
00067 iterator_composition() {}
00068 iterator_composition(iterator_composition const& it)
00069 : u(it.u), v(it.v), f(it.f) {}
00070 iterator_composition(Iterator1 u_, Iterator2 v_, BinaryFunction f_)
00071 : u(u_), v(v_), f(f_) {}
00072 iterator_composition& operator=(iterator_composition const& it)
00073 { u = it.u; v = it.v; f = it.f; return *this; }
00074
00075 bool operator==(self const& rhs) const
00076 { return u == rhs.u && v == rhs.v; }
00077 bool operator!=(self const& rhs) const
00078 { return !operator==(rhs); }
00079 self& operator++() { ++u; ++v; return *this; }
00080 self operator++(int) { self tmp = *this; ++*this; return tmp; }
00081 self& operator--() { --u; --v; return *this; }
00082 self operator--(int) { self tmp = *this; --*this; return tmp; }
00083 self& operator+=(difference_type i)
00084 { u += i; v += i; return *this; }
00085 self& operator-=(difference_type i)
00086 { u -= i; v -= i; return *this; }
00087 self operator+(difference_type i) const
00088 { self tmp = *this; tmp += i; return tmp; }
00089 friend self operator+(difference_type n, self const& u)
00090 { self tmp = u; tmp += i; return tmp; }
00091 self operator-(difference_type i) const
00092 { self tmp = *this; tmp -= i; return tmp; }
00093 difference_type operator-(self const& rhs) const
00094 { return u - rhs.u; }
00095
00096 value_type operator*() const { return f(*u, *v); }
00097 value_type operator[](difference_type i) const
00098 { return f(u[i], v[i]); }
00099 private:
00100 Iterator1 u;
00101 Iterator2 v;
00102 BinaryFunction f;
00103 };
00104
00105 template<typename Iterator1, typename Iterator2, typename BinaryFunction>
00106 inline iterator_composition<Iterator1, Iterator2, BinaryFunction>
00107 compose_iterators(Iterator1 it1, Iterator2 it2, BinaryFunction f) {
00108 return iterator_composition<Iterator1, Iterator2, BinaryFunction>
00109 (it1, it2, f);
00110 }
00111
00112 }}
00113
00114 #endif