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
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 }
00120 #endif // UTIL_SIZED_ITERATOR_H