Commit 03784170 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Add bidi support to IteratorFacade

Summary: [Folly] Add bidi support to IteratorFacade

Reviewed By: aary

Differential Revision: D10477733

fbshipit-source-id: 6779580a4fdea88d29fb51454da04c9605b026bb
parent 611dae9a
......@@ -50,10 +50,11 @@ namespace folly {
namespace detail {
/**
* Currently this only supports forward iteration. The derived class must
* must have definitions for these three methods:
* Currently this only supports forward and bidirectional iteration. The
* derived class must must have definitions for these methods:
*
* void increment();
* void decrement(); // optional, to be used with bidirectional
* reference dereference() const;
* bool equal([appropriate iterator type] const& rhs) const;
*
......@@ -63,15 +64,18 @@ namespace detail {
* Template parameters:
* D: the deriving class (CRTP)
* V: value type
* Tag: the iterator category, one of:
* std::forward_iterator_tag
* std::bidirectional_iterator_tag
*/
template <class D, class V>
template <class D, class V, class Tag>
class IteratorFacade {
public:
using value_type = V;
using reference = value_type&;
using pointer = value_type*;
using difference_type = ssize_t;
using iterator_category = std::forward_iterator_tag;
using iterator_category = Tag;
bool operator==(D const& rhs) const {
return asDerivedConst().equal(rhs);
......@@ -119,6 +123,17 @@ class IteratorFacade {
return ret;
}
D& operator--() {
asDerived().decrement();
return asDerived();
}
D operator--(int) {
auto ret = asDerived(); // copy
asDerived().decrement();
return ret;
}
private:
D& asDerived() {
return static_cast<D&>(*this);
......@@ -138,10 +153,10 @@ class IteratorFacade {
* I: the wrapper iterator type
* V: value type
*/
template <class D, class I, class V>
class IteratorAdaptor : public IteratorFacade<D, V> {
template <class D, class I, class V, class Tag>
class IteratorAdaptor : public IteratorFacade<D, V, Tag> {
public:
using Super = IteratorFacade<D, V>;
using Super = IteratorFacade<D, V, Tag>;
using value_type = typename Super::value_type;
using iterator_category = typename Super::iterator_category;
using reference = typename Super::reference;
......@@ -149,10 +164,15 @@ class IteratorAdaptor : public IteratorFacade<D, V> {
using difference_type = typename Super::difference_type;
explicit IteratorAdaptor(I base) : base_(base) {}
void increment() {
++base_;
}
void decrement() {
--base_;
}
V& dereference() const {
return *base_;
}
......
......@@ -249,11 +249,13 @@ inline dynamic::ObjectMaker dynamic::object(dynamic a, dynamic b) {
struct dynamic::item_iterator : detail::IteratorAdaptor<
dynamic::item_iterator,
dynamic::ObjectImpl::iterator,
std::pair<dynamic const, dynamic>> {
std::pair<dynamic const, dynamic>,
std::forward_iterator_tag> {
using Super = detail::IteratorAdaptor<
dynamic::item_iterator,
dynamic::ObjectImpl::iterator,
std::pair<dynamic const, dynamic>>;
std::pair<dynamic const, dynamic>,
std::forward_iterator_tag>;
/* implicit */ item_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
using object_type = dynamic::ObjectImpl;
......@@ -262,11 +264,13 @@ struct dynamic::item_iterator : detail::IteratorAdaptor<
struct dynamic::value_iterator : detail::IteratorAdaptor<
dynamic::value_iterator,
dynamic::ObjectImpl::iterator,
dynamic> {
dynamic,
std::forward_iterator_tag> {
using Super = detail::IteratorAdaptor<
dynamic::value_iterator,
dynamic::ObjectImpl::iterator,
dynamic>;
dynamic,
std::forward_iterator_tag>;
/* implicit */ value_iterator(dynamic::ObjectImpl::iterator b) : Super(b) {}
using object_type = dynamic::ObjectImpl;
......@@ -280,11 +284,13 @@ struct dynamic::const_item_iterator
: detail::IteratorAdaptor<
dynamic::const_item_iterator,
dynamic::ObjectImpl::const_iterator,
std::pair<dynamic const, dynamic> const> {
std::pair<dynamic const, dynamic> const,
std::forward_iterator_tag> {
using Super = detail::IteratorAdaptor<
dynamic::const_item_iterator,
dynamic::ObjectImpl::const_iterator,
std::pair<dynamic const, dynamic> const>;
std::pair<dynamic const, dynamic> const,
std::forward_iterator_tag>;
/* implicit */ const_item_iterator(dynamic::ObjectImpl::const_iterator b)
: Super(b) {}
/* implicit */ const_item_iterator(const_item_iterator const& i)
......@@ -297,11 +303,13 @@ struct dynamic::const_item_iterator
struct dynamic::const_key_iterator : detail::IteratorAdaptor<
dynamic::const_key_iterator,
dynamic::ObjectImpl::const_iterator,
dynamic const> {
dynamic const,
std::forward_iterator_tag> {
using Super = detail::IteratorAdaptor<
dynamic::const_key_iterator,
dynamic::ObjectImpl::const_iterator,
dynamic const>;
dynamic const,
std::forward_iterator_tag>;
/* implicit */ const_key_iterator(dynamic::ObjectImpl::const_iterator b)
: Super(b) {}
......@@ -315,11 +323,13 @@ struct dynamic::const_key_iterator : detail::IteratorAdaptor<
struct dynamic::const_value_iterator : detail::IteratorAdaptor<
dynamic::const_value_iterator,
dynamic::ObjectImpl::const_iterator,
dynamic const> {
dynamic const,
std::forward_iterator_tag> {
using Super = detail::IteratorAdaptor<
dynamic::const_value_iterator,
dynamic::ObjectImpl::const_iterator,
dynamic const>;
dynamic const,
std::forward_iterator_tag>;
/* implicit */ const_value_iterator(dynamic::ObjectImpl::const_iterator b)
: Super(b) {}
/* implicit */ const_value_iterator(value_iterator i) : Super(i.base()) {}
......
......@@ -1610,8 +1610,10 @@ inline std::unique_ptr<IOBuf> IOBuf::maybeCopyBuffer(
return copyBuffer(buf.data(), buf.size(), headroom, minTailroom);
}
class IOBuf::Iterator
: public detail::IteratorFacade<IOBuf::Iterator, ByteRange const> {
class IOBuf::Iterator : public detail::IteratorFacade<
IOBuf::Iterator,
ByteRange const,
std::forward_iterator_tag> {
public:
// Note that IOBufs are stored as a circular list without a guard node,
// so pos == end is ambiguous (it may mean "begin" or "end"). To solve
......
......@@ -24,7 +24,8 @@ using namespace folly::detail;
using namespace folly;
namespace {
struct IntArrayIterator : IteratorFacade<IntArrayIterator, int const> {
struct IntArrayIterator
: IteratorFacade<IntArrayIterator, int const, std::forward_iterator_tag> {
explicit IntArrayIterator(int const* a) : a_(a) {}
void increment() {
++a_;
......@@ -68,8 +69,16 @@ TEST(IteratorsTest, SimpleIteratorFacade) {
namespace {
// Simple iterator adaptor: wraps an int pointer.
struct IntPointerIter : IteratorAdaptor<IntPointerIter, int const*, int const> {
using Super = IteratorAdaptor<IntPointerIter, int const*, int const>;
struct IntPointerIter : IteratorAdaptor<
IntPointerIter,
int const*,
int const,
std::forward_iterator_tag> {
using Super = IteratorAdaptor<
IntPointerIter,
int const*,
int const,
std::forward_iterator_tag>;
explicit IntPointerIter(int const* ptr) : Super(ptr) {}
};
} // namespace
......@@ -104,20 +113,32 @@ TEST(IteratorsTest, IterAdaptorWithPointer) {
namespace {
// More complex case: wrap a map iterator, but these provide either the key or
// value.
struct IntMapKeyIter
: IteratorAdaptor<IntMapKeyIter, std::map<int, int>::iterator, int const> {
using Super =
IteratorAdaptor<IntMapKeyIter, std::map<int, int>::iterator, int const>;
struct IntMapKeyIter : IteratorAdaptor<
IntMapKeyIter,
std::map<int, int>::iterator,
int const,
std::forward_iterator_tag> {
using Super = IteratorAdaptor<
IntMapKeyIter,
std::map<int, int>::iterator,
int const,
std::forward_iterator_tag>;
explicit IntMapKeyIter(std::map<int, int>::iterator iter) : Super(iter) {}
int const& dereference() const {
return base()->first;
}
};
struct IntMapValueIter
: IteratorAdaptor<IntMapValueIter, std::map<int, int>::iterator, int> {
using Super =
IteratorAdaptor<IntMapValueIter, std::map<int, int>::iterator, int>;
struct IntMapValueIter : IteratorAdaptor<
IntMapValueIter,
std::map<int, int>::iterator,
int,
std::forward_iterator_tag> {
using Super = IteratorAdaptor<
IntMapValueIter,
std::map<int, int>::iterator,
int,
std::forward_iterator_tag>;
explicit IntMapValueIter(std::map<int, int>::iterator iter) : Super(iter) {}
int& dereference() const {
return base()->second;
......@@ -160,11 +181,13 @@ namespace {
struct IntMapValueIterConst : IteratorAdaptor<
IntMapValueIterConst,
std::map<int, int>::const_iterator,
int const> {
int const,
std::forward_iterator_tag> {
using Super = IteratorAdaptor<
IntMapValueIterConst,
std::map<int, int>::const_iterator,
int const>;
int const,
std::forward_iterator_tag>;
explicit IntMapValueIterConst(std::map<int, int>::const_iterator iter)
: Super(iter) {}
/* implicit */ IntMapValueIterConst(IntMapValueIter const& rhs)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment