#ifndef UTIL_SIZED_ITERATOR_H #define UTIL_SIZED_ITERATOR_H #include "util/proxy_iterator.hh" #include #include #include #include #include namespace util { class SizedInnerIterator { public: SizedInnerIterator() {} SizedInnerIterator(void *ptr, std::size_t size) : ptr_(static_cast(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(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(first.inner_.Data()), static_cast(first.inner_.Data()) + first.inner_.EntrySize(), static_cast(second.inner_.Data())); } private: friend class util::ProxyIterator; typedef std::string value_type; typedef SizedInnerIterator InnerIterator; InnerIterator &Inner() { return inner_; } const InnerIterator &Inner() const { return inner_; } InnerIterator inner_; }; typedef ProxyIterator 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 SizedCompare : public std::binary_function { 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