Joshua
open source statistical hierarchical phrase-based machine translation system
|
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