summaryrefslogtreecommitdiff
path: root/klm/util/proxy_iterator.hh
diff options
context:
space:
mode:
authorredpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f>2010-10-18 23:24:01 +0000
committerredpony <redpony@ec762483-ff6d-05da-a07a-a48fb63a330f>2010-10-18 23:24:01 +0000
commite0ef743090038ee02d656cee11debd2246624ba0 (patch)
treee5e1d32402c8dcb490c574e24c087c56d4cc172e /klm/util/proxy_iterator.hh
parent0c2514868f58bbfe422aa275e2905182cf2f57eb (diff)
kenneth's LM preliminary integration
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@681 ec762483-ff6d-05da-a07a-a48fb63a330f
Diffstat (limited to 'klm/util/proxy_iterator.hh')
-rw-r--r--klm/util/proxy_iterator.hh94
1 files changed, 94 insertions, 0 deletions
diff --git a/klm/util/proxy_iterator.hh b/klm/util/proxy_iterator.hh
new file mode 100644
index 00000000..1c5b7089
--- /dev/null
+++ b/klm/util/proxy_iterator.hh
@@ -0,0 +1,94 @@
+#ifndef UTIL_PROXY_ITERATOR__
+#define UTIL_PROXY_ITERATOR__
+
+#include <cstddef>
+#include <iterator>
+
+/* This is a RandomAccessIterator that uses a proxy to access the underlying
+ * data. Useful for packing data at bit offsets but still using STL
+ * algorithms.
+ *
+ * Normally I would use boost::iterator_facade but some people are too lazy to
+ * install boost and still want to use my language model. It's amazing how
+ * many operators an iterator has.
+ *
+ * The Proxy needs to provide:
+ * class InnerIterator;
+ * InnerIterator &Inner();
+ * const InnerIterator &Inner() const;
+ *
+ * InnerIterator has to implement:
+ * operator==(InnerIterator)
+ * operator<(InnerIterator)
+ * operator+=(std::ptrdiff_t)
+ * operator-(InnerIterator)
+ * and of course whatever Proxy needs to dereference it.
+ *
+ * It's also a good idea to specialize std::swap for Proxy.
+ */
+
+namespace util {
+template <class Proxy> class ProxyIterator {
+ private:
+ // Self.
+ typedef ProxyIterator<Proxy> S;
+ typedef typename Proxy::InnerIterator InnerIterator;
+
+ public:
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef typename Proxy::value_type value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef Proxy reference;
+ typedef Proxy * pointer;
+
+ ProxyIterator() {}
+
+ // For cast from non const to const.
+ template <class AlternateProxy> ProxyIterator(const ProxyIterator<AlternateProxy> &in) : p_(*in) {}
+ explicit ProxyIterator(const Proxy &p) : p_(p) {}
+
+ // p_'s operator= does value copying, but here we want iterator copying.
+ S &operator=(const S &other) {
+ I() = other.I();
+ return *this;
+ }
+
+ bool operator==(const S &other) const { return I() == other.I(); }
+ bool operator!=(const S &other) const { return !(*this == other); }
+ bool operator<(const S &other) const { return I() < other.I(); }
+ bool operator>(const S &other) const { return other < *this; }
+ bool operator<=(const S &other) const { return !(*this > other); }
+ bool operator>=(const S &other) const { return !(*this < other); }
+
+ S &operator++() { return *this += 1; }
+ S operator++(int) { S ret(*this); ++*this; return ret; }
+ S &operator+=(std::ptrdiff_t amount) { I() += amount; return *this; }
+ S operator+(std::ptrdiff_t amount) const { S ret(*this); ret += amount; return ret; }
+
+ S &operator--() { return *this -= 1; }
+ S operator--(int) { S ret(*this); --*this; return ret; }
+ S &operator-=(std::ptrdiff_t amount) { I() += (-amount); return *this; }
+ S operator-(std::ptrdiff_t amount) const { S ret(*this); ret -= amount; return ret; }
+
+ std::ptrdiff_t operator-(const S &other) const { return I() - other.I(); }
+
+ Proxy operator*() { return p_; }
+ const Proxy operator*() const { return p_; }
+ Proxy *operator->() { return &p_; }
+ const Proxy *operator->() const { return &p_; }
+ Proxy operator[](std::ptrdiff_t amount) const { return *(*this + amount); }
+
+ private:
+ InnerIterator &I() { return p_.Inner(); }
+ const InnerIterator &I() const { return p_.Inner(); }
+
+ Proxy p_;
+};
+
+template <class Proxy> ProxyIterator<Proxy> operator+(std::ptrdiff_t amount, const ProxyIterator<Proxy> &it) {
+ return it + amount;
+}
+
+} // namespace util
+
+#endif // UTIL_PROXY_ITERATOR__