00001
00002
00003
00004 #ifndef PROXY_ITERATOR_H_
00005 #define PROXY_ITERATOR_H_
00006 #include <algorithm>
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 template<bool, class T>
00022 struct EnableIf_c
00023 {
00024
00025 typedef T type;
00026 };
00027 template<class T>
00028 struct EnableIf_c<false, T>
00029 {
00030
00031
00032 private:
00033 class Invalid {};
00034 public:
00035 typedef Invalid type;
00036 };
00037 template <class Cond, class T>
00038 struct EnableIf: EnableIf_c<Cond::value, T>
00039 {
00040 };
00041 template <class T, class U>
00042 struct IsSame
00043 {
00044 static const bool value = false;
00045 };
00046 template <class T>
00047 struct IsSame<T,T>
00048 {
00049 static const bool value = true;
00050 };
00051 template <class T>
00052 struct Not
00053 {
00054 static const bool value = ! T::value;
00055 };
00056
00057 template<class P, class C>
00058 class ProxyIterator
00059 {
00060 P proxy;
00061 typedef EnableIf<Not<IsSame<P,C> >,
00062 ProxyIterator<C,C> > const_iterator_type_1;
00063 typedef typename const_iterator_type_1::type const_iterator_type;
00064 public:
00065 typedef P value_type;
00066 typedef int difference_type;
00067 typedef random_access_iterator_tag iterator_category;
00068 typedef const value_type &reference;
00069 typedef const value_type *pointer;
00070
00071 explicit ProxyIterator(typename P::list_type* list, int index) :
00072 proxy(list, index) {}
00073 ProxyIterator(const ProxyIterator &other) :
00074 proxy(other.proxy.m_list, other.proxy.m_index) {}
00075 explicit ProxyIterator(void) : proxy(NULL, 0) {}
00076 ProxyIterator &operator=(ProxyIterator other)
00077 {
00078 swap(other);
00079 return *this;
00080 }
00081 operator const_iterator_type() const
00082 {
00083 return const_iterator_type(proxy.m_list, proxy.m_index);
00084 }
00085
00086 void swap(ProxyIterator other)
00087 {
00088 std::swap(proxy.m_list,other.proxy.m_list);
00089 std::swap(proxy.m_index,other.proxy.m_index);
00090 }
00091
00092 bool associated() const
00093 {
00094 return proxy.m_list != NULL;
00095 }
00096
00097 bool equals(const ProxyIterator &other) const
00098 {
00099 return other.proxy.m_list == proxy.m_list &&
00100 other.proxy.m_index == proxy.m_index;
00101 }
00102
00103 reference operator*() const
00104 {
00105 return proxy;
00106 }
00107 pointer operator->() const
00108 {
00109
00110
00111 return &proxy;
00112 }
00113
00114 ProxyIterator& operator++()
00115 {
00116 ++proxy.m_index;
00117 return *this;
00118 }
00119 ProxyIterator operator++(int)
00120 {
00121 ProxyIterator old(*this);
00122 ++*this;
00123 return old;
00124 }
00125 ProxyIterator& operator--()
00126 {
00127 --proxy.m_index;
00128 return *this;
00129 }
00130 ProxyIterator operator--(int)
00131 {
00132 ProxyIterator old(*this);
00133 --*this;
00134 return old;
00135 }
00136
00137
00138 const ProxyIterator add(difference_type i) const
00139 {
00140 return ProxyIterator(proxy.m_list,proxy.m_index+i);
00141 }
00142
00143 difference_type diff(const ProxyIterator &other) const
00144 {
00145 return proxy.m_index - other.proxy.m_index;
00146 }
00147
00148 int cmp(const ProxyIterator &other) const
00149 {
00150 if (proxy.m_index == other.proxy.m_index)
00151 return 0;
00152 else if (proxy.m_index > other.proxy.m_index)
00153 return 1;
00154 else
00155 return -1;
00156 }
00157
00158 ProxyIterator& operator+=(difference_type i)
00159 {
00160 proxy.m_index += i;
00161 return *this;
00162 }
00163 ProxyIterator &operator-=(difference_type i)
00164 {
00165 proxy.m_index -= i;
00166 return *this;
00167 }
00168
00169 const value_type operator[](difference_type i) const
00170 {
00171 return P(proxy.m_list,proxy.m_index+i);
00172 }
00173 };
00174
00175 template<class P1, class P2, class C>
00176 inline bool operator==(const ProxyIterator<P1,C> &a,
00177 const ProxyIterator<P2,C> &b)
00178 {
00179 return ProxyIterator<C,C>(a).equals(ProxyIterator<C,C>(b));
00180 }
00181 template<class P1,class P2, class C>
00182 inline bool operator!=(const ProxyIterator<P1,C> &a,
00183 const ProxyIterator<P2,C> &b)
00184 {
00185 return !(a == b);
00186 }
00187
00188 template<class P, class C>
00189 inline const ProxyIterator<P,C> operator+(
00190 typename ProxyIterator<P,C>::difference_type i, const ProxyIterator<P,C> &a)
00191 {
00192 return a.add(i);
00193 }
00194 template<class P, class C>
00195 inline const ProxyIterator<P,C> operator+(
00196 const ProxyIterator<P,C> &a, typename ProxyIterator<P,C>::difference_type i)
00197 {
00198 return a.add(i);
00199 }
00200 template<class P, class C>
00201 inline const ProxyIterator<P,C> operator-(
00202 const ProxyIterator<P,C> &a, typename ProxyIterator<P,C>::difference_type i)
00203 {
00204 return a.add(-i);
00205 }
00206
00207 template<class P, class C>
00208 inline bool operator>(const ProxyIterator<P,C> &a,
00209 const ProxyIterator<P,C> &b)
00210 {
00211 return a.cmp(b) > 0;
00212 }
00213 template<class P, class C>
00214 inline bool operator>=(const ProxyIterator<P,C> &a,
00215 const ProxyIterator<P,C> &b)
00216 {
00217 return a.cmp(b) >= 0;
00218 }
00219 template<class P, class C>
00220 inline bool operator<(const ProxyIterator<P,C> &a,
00221 const ProxyIterator<P,C> &b)
00222 {
00223 return a.cmp(b) < 0;
00224 }
00225 template<class P, class C>
00226 inline bool operator<=(const ProxyIterator<P,C> &a,
00227 const ProxyIterator<P,C> &b)
00228 {
00229 return a.cmp(b) <= 0;
00230 }
00231
00232 template<class P, class C>
00233 inline typename ProxyIterator<P,C>::difference_type operator-(
00234 const ProxyIterator<P,C> &a, const ProxyIterator<P,C> &b)
00235 {
00236 return a.diff(b);
00237 }
00238
00239 #endif