File size: 3,525 Bytes
1ce325b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
#ifndef UTIL_SIZED_ITERATOR_H
#define UTIL_SIZED_ITERATOR_H
#include "util/proxy_iterator.hh"
#include <algorithm>
#include <functional>
#include <string>
#include <stdint.h>
#include <string.h>
namespace util {
class SizedInnerIterator {
public:
SizedInnerIterator() {}
SizedInnerIterator(void *ptr, std::size_t size) : ptr_(static_cast<uint8_t*>(ptr)), size_(size) {}
bool operator==(const SizedInnerIterator &other) const {
return ptr_ == other.ptr_;
}
bool operator<(const SizedInnerIterator &other) const {
return ptr_ < other.ptr_;
}
SizedInnerIterator &operator+=(std::ptrdiff_t amount) {
ptr_ += amount * size_;
return *this;
}
std::ptrdiff_t operator-(const SizedInnerIterator &other) const {
return (ptr_ - other.ptr_) / size_;
}
const void *Data() const { return ptr_; }
void *Data() { return ptr_; }
std::size_t EntrySize() const { return size_; }
friend void swap(SizedInnerIterator &first, SizedInnerIterator &second) {
std::swap(first.ptr_, second.ptr_);
std::swap(first.size_, second.size_);
}
private:
uint8_t *ptr_;
std::size_t size_;
};
class SizedProxy {
public:
SizedProxy() {}
SizedProxy(void *ptr, std::size_t size) : inner_(ptr, size) {}
operator std::string() const {
return std::string(reinterpret_cast<const char*>(inner_.Data()), inner_.EntrySize());
}
SizedProxy &operator=(const SizedProxy &from) {
memcpy(inner_.Data(), from.inner_.Data(), inner_.EntrySize());
return *this;
}
SizedProxy &operator=(const std::string &from) {
memcpy(inner_.Data(), from.data(), inner_.EntrySize());
return *this;
}
const void *Data() const { return inner_.Data(); }
void *Data() { return inner_.Data(); }
friend void swap(SizedProxy first, SizedProxy second) {
std::swap_ranges(
static_cast<char*>(first.inner_.Data()),
static_cast<char*>(first.inner_.Data()) + first.inner_.EntrySize(),
static_cast<char*>(second.inner_.Data()));
}
private:
friend class util::ProxyIterator<SizedProxy>;
typedef std::string value_type;
typedef SizedInnerIterator InnerIterator;
InnerIterator &Inner() { return inner_; }
const InnerIterator &Inner() const { return inner_; }
InnerIterator inner_;
};
typedef ProxyIterator<SizedProxy> SizedIterator;
inline SizedIterator SizedIt(void *ptr, std::size_t size) { return SizedIterator(SizedProxy(ptr, size)); }
// Useful wrapper for a comparison function i.e. sort.
template <class Delegate, class Proxy = SizedProxy> class SizedCompare : public std::binary_function<const Proxy &, const Proxy &, bool> {
public:
explicit SizedCompare(const Delegate &delegate = Delegate()) : delegate_(delegate) {}
bool operator()(const Proxy &first, const Proxy &second) const {
return delegate_(first.Data(), second.Data());
}
bool operator()(const Proxy &first, const std::string &second) const {
return delegate_(first.Data(), second.data());
}
bool operator()(const std::string &first, const Proxy &second) const {
return delegate_(first.data(), second.Data());
}
bool operator()(const std::string &first, const std::string &second) const {
return delegate_(first.data(), second.data());
}
const Delegate &GetDelegate() const { return delegate_; }
private:
const Delegate delegate_;
};
} // namespace util
#endif // UTIL_SIZED_ITERATOR_H
|