Joshua
open source statistical hierarchical phrase-based machine translation system
|
00001 #ifndef UTIL_PROXY_ITERATOR_H 00002 #define UTIL_PROXY_ITERATOR_H 00003 00004 #include <cstddef> 00005 #include <iterator> 00006 00007 /* This is a RandomAccessIterator that uses a proxy to access the underlying 00008 * data. Useful for packing data at bit offsets but still using STL 00009 * algorithms. 00010 * 00011 * Normally I would use boost::iterator_facade but some people are too lazy to 00012 * install boost and still want to use my language model. It's amazing how 00013 * many operators an iterator has. 00014 * 00015 * The Proxy needs to provide: 00016 * class InnerIterator; 00017 * InnerIterator &Inner(); 00018 * const InnerIterator &Inner() const; 00019 * 00020 * InnerIterator has to implement: 00021 * operator==(InnerIterator) 00022 * operator<(InnerIterator) 00023 * operator+=(std::ptrdiff_t) 00024 * operator-(InnerIterator) 00025 * and of course whatever Proxy needs to dereference it. 00026 * 00027 * It's also a good idea to specialize std::swap for Proxy. 00028 */ 00029 00030 namespace util { 00031 template <class Proxy> class ProxyIterator { 00032 private: 00033 // Self. 00034 typedef ProxyIterator<Proxy> S; 00035 typedef typename Proxy::InnerIterator InnerIterator; 00036 00037 public: 00038 typedef std::random_access_iterator_tag iterator_category; 00039 typedef typename Proxy::value_type value_type; 00040 typedef std::ptrdiff_t difference_type; 00041 typedef Proxy reference; 00042 typedef ProxyIterator<Proxy> * pointer; 00043 00044 ProxyIterator() {} 00045 00046 // For cast from non const to const. 00047 template <class AlternateProxy> ProxyIterator(const ProxyIterator<AlternateProxy> &in) : p_(*in) {} 00048 explicit ProxyIterator(const Proxy &p) : p_(p) {} 00049 00050 /* // p_'s swap does value swapping, but here we want iterator swapping 00051 friend inline void swap(ProxyIterator<Proxy> &first, ProxyIterator<Proxy> &second) { 00052 swap(first.I(), second.I()); 00053 }*/ 00054 00055 // p_'s operator= does value copying, but here we want iterator copying. 00056 S &operator=(const S &other) { 00057 I() = other.I(); 00058 return *this; 00059 } 00060 00061 bool operator==(const S &other) const { return I() == other.I(); } 00062 bool operator!=(const S &other) const { return !(*this == other); } 00063 bool operator<(const S &other) const { return I() < other.I(); } 00064 bool operator>(const S &other) const { return other < *this; } 00065 bool operator<=(const S &other) const { return !(*this > other); } 00066 bool operator>=(const S &other) const { return !(*this < other); } 00067 00068 S &operator++() { return *this += 1; } 00069 S operator++(int) { S ret(*this); ++*this; return ret; } 00070 S &operator+=(std::ptrdiff_t amount) { I() += amount; return *this; } 00071 S operator+(std::ptrdiff_t amount) const { S ret(*this); ret += amount; return ret; } 00072 00073 S &operator--() { return *this -= 1; } 00074 S operator--(int) { S ret(*this); --*this; return ret; } 00075 S &operator-=(std::ptrdiff_t amount) { I() += (-amount); return *this; } 00076 S operator-(std::ptrdiff_t amount) const { S ret(*this); ret -= amount; return ret; } 00077 00078 std::ptrdiff_t operator-(const S &other) const { return I() - other.I(); } 00079 00080 Proxy operator*() { return p_; } 00081 const Proxy operator*() const { return p_; } 00082 Proxy *operator->() { return &p_; } 00083 const Proxy *operator->() const { return &p_; } 00084 Proxy operator[](std::ptrdiff_t amount) const { return *(*this + amount); } 00085 00086 const InnerIterator &Inner() { return p_.Inner(); } 00087 00088 private: 00089 InnerIterator &I() { return p_.Inner(); } 00090 const InnerIterator &I() const { return p_.Inner(); } 00091 00092 Proxy p_; 00093 }; 00094 00095 template <class Proxy> ProxyIterator<Proxy> operator+(std::ptrdiff_t amount, const ProxyIterator<Proxy> &it) { 00096 return it + amount; 00097 } 00098 00099 } // namespace util 00100 00101 #endif // UTIL_PROXY_ITERATOR_H