00001 #ifndef UTIL_SIZED_ITERATOR__
00002 #define UTIL_SIZED_ITERATOR__
00003
00004 #include "util/proxy_iterator.hh"
00005
00006 #include <algorithm>
00007 #include <functional>
00008 #include <string>
00009
00010 #include <stdint.h>
00011 #include <string.h>
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 private:
00040 uint8_t *ptr_;
00041 std::size_t size_;
00042 };
00043
00044 class SizedProxy {
00045 public:
00046 SizedProxy() {}
00047
00048 SizedProxy(void *ptr, std::size_t size) : inner_(ptr, size) {}
00049
00050 operator std::string() const {
00051 return std::string(reinterpret_cast<const char*>(inner_.Data()), inner_.EntrySize());
00052 }
00053
00054 SizedProxy &operator=(const SizedProxy &from) {
00055 memcpy(inner_.Data(), from.inner_.Data(), inner_.EntrySize());
00056 return *this;
00057 }
00058
00059 SizedProxy &operator=(const std::string &from) {
00060 memcpy(inner_.Data(), from.data(), inner_.EntrySize());
00061 return *this;
00062 }
00063
00064 const void *Data() const { return inner_.Data(); }
00065 void *Data() { return inner_.Data(); }
00066
00067 friend void swap(SizedProxy &first, SizedProxy &second) {
00068 std::swap_ranges(
00069 static_cast<char*>(first.inner_.Data()),
00070 static_cast<char*>(first.inner_.Data()) + first.inner_.EntrySize(),
00071 static_cast<char*>(second.inner_.Data()));
00072 }
00073
00074 private:
00075 friend class util::ProxyIterator<SizedProxy>;
00076
00077 typedef std::string value_type;
00078
00079 typedef SizedInnerIterator InnerIterator;
00080
00081 InnerIterator &Inner() { return inner_; }
00082 const InnerIterator &Inner() const { return inner_; }
00083 InnerIterator inner_;
00084 };
00085
00086 typedef ProxyIterator<SizedProxy> SizedIterator;
00087
00088 inline SizedIterator SizedIt(void *ptr, std::size_t size) { return SizedIterator(SizedProxy(ptr, size)); }
00089
00090
00091 template <class Delegate, class Proxy = SizedProxy> class SizedCompare : public std::binary_function<const Proxy &, const Proxy &, bool> {
00092 public:
00093 explicit SizedCompare(const Delegate &delegate = Delegate()) : delegate_(delegate) {}
00094
00095 bool operator()(const Proxy &first, const Proxy &second) const {
00096 return delegate_(first.Data(), second.Data());
00097 }
00098 bool operator()(const Proxy &first, const std::string &second) const {
00099 return delegate_(first.Data(), second.data());
00100 }
00101 bool operator()(const std::string &first, const Proxy &second) const {
00102 return delegate_(first.data(), second.Data());
00103 }
00104 bool operator()(const std::string &first, const std::string &second) const {
00105 return delegate_(first.data(), second.data());
00106 }
00107
00108 const Delegate &GetDelegate() const { return delegate_; }
00109
00110 private:
00111 const Delegate delegate_;
00112 };
00113
00114 }
00115 #endif // UTIL_SIZED_ITERATOR__