Joshua
open source statistical hierarchical phrase-based machine translation system
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends
src/kenlm/util/sized_iterator.hh
00001 #ifndef UTIL_SIZED_ITERATOR_H
00002 #define UTIL_SIZED_ITERATOR_H
00003 
00004 #include "util/proxy_iterator.hh"
00005 
00006 #include <algorithm>
00007 #include <functional>
00008 #include <string>
00009 
00010 #include <stdint.h>
00011 #include <cstring>
00012 
00013 namespace util {
00014 
00015 class SizedInnerIterator {
00016   public:
00017     SizedInnerIterator() {}
00018 
00019     SizedInnerIterator(void *ptr, std::size_t size) : ptr_(static_cast<uint8_t*>(ptr)), size_(size) {}
00020 
00021     bool operator==(const SizedInnerIterator &other) const {
00022       return ptr_ == other.ptr_;
00023     }
00024     bool operator<(const SizedInnerIterator &other) const {
00025       return ptr_ < other.ptr_;
00026     }
00027     SizedInnerIterator &operator+=(std::ptrdiff_t amount) {
00028       ptr_ += amount * size_;
00029       return *this;
00030     }
00031     std::ptrdiff_t operator-(const SizedInnerIterator &other) const {
00032       return (ptr_ - other.ptr_) / size_;
00033     }
00034 
00035     const void *Data() const { return ptr_; }
00036     void *Data() { return ptr_; }
00037     std::size_t EntrySize() const { return size_; }
00038 
00039     friend void swap(SizedInnerIterator &first, SizedInnerIterator &second) {
00040       std::swap(first.ptr_, second.ptr_);
00041       std::swap(first.size_, second.size_);
00042     }
00043 
00044   private:
00045     uint8_t *ptr_;
00046     std::size_t size_;
00047 };
00048 
00049 class SizedProxy {
00050   public:
00051     SizedProxy() {}
00052 
00053     SizedProxy(void *ptr, std::size_t size) : inner_(ptr, size) {}
00054 
00055     operator std::string() const {
00056       return std::string(reinterpret_cast<const char*>(inner_.Data()), inner_.EntrySize());
00057     }
00058 
00059     SizedProxy &operator=(const SizedProxy &from) {
00060       memcpy(inner_.Data(), from.inner_.Data(), inner_.EntrySize());
00061       return *this;
00062     }
00063 
00064     SizedProxy &operator=(const std::string &from) {
00065       memcpy(inner_.Data(), from.data(), inner_.EntrySize());
00066       return *this;
00067     }
00068 
00069     const void *Data() const { return inner_.Data(); }
00070     void *Data() { return inner_.Data(); }
00071 
00072     friend void swap(SizedProxy first, SizedProxy second) {
00073       std::swap_ranges(
00074           static_cast<char*>(first.inner_.Data()),
00075           static_cast<char*>(first.inner_.Data()) + first.inner_.EntrySize(),
00076           static_cast<char*>(second.inner_.Data()));
00077     }
00078 
00079   private:
00080     friend class util::ProxyIterator<SizedProxy>;
00081 
00082     typedef std::string value_type;
00083 
00084     typedef SizedInnerIterator InnerIterator;
00085 
00086     InnerIterator &Inner() { return inner_; }
00087     const InnerIterator &Inner() const { return inner_; }
00088     InnerIterator inner_;
00089 };
00090 
00091 typedef ProxyIterator<SizedProxy> SizedIterator;
00092 
00093 inline SizedIterator SizedIt(void *ptr, std::size_t size) { return SizedIterator(SizedProxy(ptr, size)); }
00094 
00095 // Useful wrapper for a comparison function i.e. sort.
00096 template <class Delegate, class Proxy = SizedProxy> class SizedCompare : public std::binary_function<const Proxy &, const Proxy &, bool> {
00097   public:
00098     explicit SizedCompare(const Delegate &delegate = Delegate()) : delegate_(delegate) {}
00099 
00100     bool operator()(const Proxy &first, const Proxy &second) const {
00101       return delegate_(first.Data(), second.Data());
00102     }
00103     bool operator()(const Proxy &first, const std::string &second) const {
00104       return delegate_(first.Data(), second.data());
00105     }
00106     bool operator()(const std::string &first, const Proxy &second) const {
00107       return delegate_(first.data(), second.Data());
00108     }
00109     bool operator()(const std::string &first, const std::string &second) const {
00110       return delegate_(first.data(), second.data());
00111     }
00112 
00113     const Delegate &GetDelegate() const { return delegate_; }
00114 
00115   private:
00116     const Delegate delegate_;
00117 };
00118 
00119 } // namespace util
00120 #endif // UTIL_SIZED_ITERATOR_H