Extracted class Composable from BaseIterator.
Added iter::Virtual. Indexes::for_all now return iter::Virtual
This commit is contained in:
146
include/utils/iterator/composable.hpp
Normal file
146
include/utils/iterator/composable.hpp
Normal file
@@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/crtp.hpp"
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
// class EdgeType;
|
||||
|
||||
namespace iter
|
||||
{
|
||||
template <class I, class OP>
|
||||
auto make_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_filter(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class C>
|
||||
void for_all(I &&iter, C &&consumer);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_flat_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_inspect(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_limited_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_virtual(I &&iter);
|
||||
|
||||
// Class for creating easy composable iterators fo querying.
|
||||
// Derived - type of derived class
|
||||
// T - return type
|
||||
template <class T, class Derived>
|
||||
class Composable : public Crtp<Derived>
|
||||
{
|
||||
// Moves self
|
||||
Derived &&move() { return std::move(this->derived()); }
|
||||
public:
|
||||
auto virtualize() { return iter::make_virtual(move()); }
|
||||
|
||||
template <class OP>
|
||||
auto map(OP &&op)
|
||||
{
|
||||
return iter::make_map<Derived, OP>(move(), std::move(op));
|
||||
}
|
||||
|
||||
template <class OP>
|
||||
auto filter(OP &&op)
|
||||
{
|
||||
return iter::make_filter<Derived, OP>(move(), std::move(op));
|
||||
}
|
||||
|
||||
// Replaces every item with item taken from n if it exists.
|
||||
template <class R>
|
||||
auto replace(Option<R> &n)
|
||||
{
|
||||
return iter::make_limited_map<Derived>(
|
||||
move(), [&](auto v) mutable { return std::move(n); });
|
||||
}
|
||||
|
||||
// Maps with call to method to() and filters with call to fill.
|
||||
auto to()
|
||||
{
|
||||
return map([](auto er) { return er.to(); }).fill();
|
||||
}
|
||||
|
||||
// Maps with call to method from() and filters with call to fill.
|
||||
auto from()
|
||||
{
|
||||
return map([](auto er) { return er.from(); }).fill();
|
||||
}
|
||||
|
||||
// Combines out iterators into one iterator.
|
||||
auto out()
|
||||
{
|
||||
return iter::make_flat_map<Derived>(
|
||||
move(), [](auto vr) { return vr.out().fill(); });
|
||||
}
|
||||
|
||||
// Filters with label on from vertex.
|
||||
template <class LABEL>
|
||||
auto from_label(LABEL const &label)
|
||||
{
|
||||
return filter([&](auto &ra) {
|
||||
auto va = ra.from();
|
||||
return va.fill() && va.has_label(label);
|
||||
});
|
||||
}
|
||||
|
||||
// Filters with property under given key
|
||||
template <class KEY, class PROP>
|
||||
auto has_property(KEY &key, PROP const &prop)
|
||||
{
|
||||
return filter([&](auto &va) { return va.at(key) == prop; });
|
||||
}
|
||||
|
||||
// Copy-s all pasing value to t before they are returned.
|
||||
// auto clone_to(Option<T> &t)
|
||||
// {
|
||||
// return iter::make_inspect<decltype(std::move(*this))>(
|
||||
// std::move(*this), [&](auto &v) { t = Option<T>(v); });
|
||||
// }
|
||||
|
||||
// Copy-s pasing value to t before they are returned.
|
||||
auto clone_to(Option<const T> &t)
|
||||
{
|
||||
return iter::make_inspect<Derived>(
|
||||
move(), [&](auto &v) mutable { t = Option<const T>(v); });
|
||||
}
|
||||
|
||||
// Filters with call to method fill()
|
||||
auto fill()
|
||||
{
|
||||
return filter([](auto &ra) { return ra.fill(); });
|
||||
}
|
||||
|
||||
// Filters with type
|
||||
template <class TYPE>
|
||||
auto type(TYPE const &type)
|
||||
{
|
||||
return filter([&](auto &ra) { return ra.edge_type() == type; });
|
||||
}
|
||||
|
||||
// Filters with label.
|
||||
template <class LABEL>
|
||||
auto label(LABEL const &label)
|
||||
{
|
||||
return filter([&](auto &va) { return va.has_label(label); });
|
||||
}
|
||||
|
||||
// Filters out vertices which are connected.
|
||||
auto isolated()
|
||||
{
|
||||
return filter([&](auto &ra) { return ra.isolated(); });
|
||||
}
|
||||
|
||||
// For all items calls OP.
|
||||
template <class OP>
|
||||
void for_all(OP &&op)
|
||||
{
|
||||
iter::for_all(move(), std::move(op));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -12,11 +12,7 @@ public:
|
||||
|
||||
Count(size_t min, size_t max) : min(min), max(max) {}
|
||||
|
||||
Count &min_zero()
|
||||
{
|
||||
min = 0;
|
||||
return *this;
|
||||
}
|
||||
Count min_zero() const { return Count(0, max); }
|
||||
|
||||
size_t avg() const { return ((max - min) >> 1) + min; }
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
@@ -12,7 +12,7 @@ namespace iter
|
||||
// I - iterator type
|
||||
// OP - type of filter function. OP: T& -> bool
|
||||
template <class T, class I, class OP>
|
||||
class Filter : public IteratorBase<T>
|
||||
class Filter : public IteratorBase<T>, public Composable<T, Filter<T, I, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
|
||||
@@ -12,7 +15,8 @@ namespace iter
|
||||
// J - iterator type returned from OP
|
||||
// OP - type of mapper function
|
||||
template <class T, class I, class J, class OP>
|
||||
class FlatMap : public IteratorBase<T>
|
||||
class FlatMap : public IteratorBase<T>,
|
||||
public Composable<T, FlatMap<T, I, J, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
@@ -13,7 +13,7 @@ namespace iter
|
||||
// I - iterator type
|
||||
// OP - type of inspector function. OP: T&->void
|
||||
template <class T, class I, class OP>
|
||||
class Inspect : public IteratorBase<T>
|
||||
class Inspect : public IteratorBase<T>, public Composable<T, Inspect<T, I, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
@@ -12,3 +12,4 @@
|
||||
#include "utils/iterator/limited_map.hpp"
|
||||
#include "utils/iterator/map.hpp"
|
||||
#include "utils/iterator/range_iterator.hpp"
|
||||
#include "utils/iterator/virtual_iter.hpp"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
@@ -11,7 +11,8 @@ namespace iter
|
||||
// I - iterator type gotten from accessor
|
||||
// A - accessor type
|
||||
template <class T, class I, class A>
|
||||
class IteratorAccessor : public IteratorBase<T>
|
||||
class IteratorAccessor : public IteratorBase<T>,
|
||||
public Composable<T, IteratorAccessor<T, I, A>>
|
||||
{
|
||||
public:
|
||||
IteratorAccessor() = delete;
|
||||
|
||||
@@ -3,29 +3,6 @@
|
||||
#include "utils/iterator/count.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
class EdgeType;
|
||||
|
||||
namespace iter
|
||||
{
|
||||
template <class I, class OP>
|
||||
auto make_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_filter(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class C>
|
||||
void for_all(I &&iter, C &&consumer);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_flat_map(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_inspect(I &&iter, OP &&op);
|
||||
|
||||
template <class I, class OP>
|
||||
auto make_limited_map(I &&iter, OP &&op);
|
||||
}
|
||||
|
||||
// Base iterator for next() kind iterator.
|
||||
// T - type of return value
|
||||
template <class T>
|
||||
@@ -36,110 +13,5 @@ public:
|
||||
|
||||
virtual Option<T> next() = 0;
|
||||
|
||||
virtual Count count() { return Count(0, ~((size_t)0)); }
|
||||
|
||||
template <class OP>
|
||||
auto map(OP &&op)
|
||||
{
|
||||
return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
|
||||
std::move(op));
|
||||
}
|
||||
|
||||
template <class OP>
|
||||
auto filter(OP &&op)
|
||||
{
|
||||
return iter::make_filter<decltype(std::move(*this)), OP>(
|
||||
std::move(*this), std::move(op));
|
||||
}
|
||||
|
||||
// Replaces every item with item taken from n if it exists.
|
||||
template <class R>
|
||||
auto replace(Option<R> &n)
|
||||
{
|
||||
return iter::make_limited_map<decltype(std::move(*this))>(
|
||||
std::move(*this), [&](auto v) mutable { return std::move(n); });
|
||||
}
|
||||
|
||||
// Maps with call to method to() and filters with call to fill.
|
||||
auto to()
|
||||
{
|
||||
return map([](auto er) { return er.to(); }).fill();
|
||||
}
|
||||
|
||||
// Maps with call to method from() and filters with call to fill.
|
||||
auto from()
|
||||
{
|
||||
return map([](auto er) { return er.from(); }).fill();
|
||||
}
|
||||
|
||||
// Combines out iterators into one iterator.
|
||||
auto out()
|
||||
{
|
||||
return iter::make_flat_map<decltype(std::move(*this))>(
|
||||
std::move(*this), [](auto vr) { return vr.out().fill(); });
|
||||
}
|
||||
|
||||
// Filters with label on from vertex.
|
||||
template <class LABEL>
|
||||
auto from_label(LABEL const &label)
|
||||
{
|
||||
return filter([&](auto &ra) {
|
||||
auto va = ra.from();
|
||||
return va.fill() && va.has_label(label);
|
||||
});
|
||||
}
|
||||
|
||||
// Filters with property under given key
|
||||
template <class KEY, class PROP>
|
||||
auto has_property(KEY &key, PROP const &prop)
|
||||
{
|
||||
return filter([&](auto &va) { return va.at(key) == prop; });
|
||||
}
|
||||
|
||||
// Copy-s all pasing value to t before they are returned.
|
||||
// auto clone_to(Option<T> &t)
|
||||
// {
|
||||
// return iter::make_inspect<decltype(std::move(*this))>(
|
||||
// std::move(*this), [&](auto &v) { t = Option<T>(v); });
|
||||
// }
|
||||
|
||||
// Copy-s pasing value to t before they are returned.
|
||||
auto clone_to(Option<const T> &t)
|
||||
{
|
||||
return iter::make_inspect<decltype(std::move(*this))>(
|
||||
std::move(*this), [&](auto &v) mutable { t = Option<const T>(v); });
|
||||
}
|
||||
|
||||
// Filters with call to method fill()
|
||||
auto fill()
|
||||
{
|
||||
return filter([](auto &ra) { return ra.fill(); });
|
||||
}
|
||||
|
||||
// Filters with type
|
||||
template <class TYPE>
|
||||
auto type(TYPE const &type)
|
||||
{
|
||||
return filter([&](auto &ra) { return ra.edge_type() == type; });
|
||||
}
|
||||
|
||||
// Filters with label.
|
||||
template <class LABEL>
|
||||
auto label(LABEL const &label)
|
||||
{
|
||||
return filter([&](auto &va) { return va.has_label(label); });
|
||||
}
|
||||
|
||||
// Filters out vertices which are connected.
|
||||
auto isolated()
|
||||
{
|
||||
return filter([&](auto &ra) { return ra.isolated(); });
|
||||
}
|
||||
|
||||
// For all items calls OP.
|
||||
template <class OP>
|
||||
void for_all(OP &&op)
|
||||
{
|
||||
iter::for_all(std::move(*this), std::move(op));
|
||||
}
|
||||
virtual Count count() = 0;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter
|
||||
@@ -8,7 +9,8 @@ namespace iter
|
||||
// T - type of return value
|
||||
// F - type of wraped lambda
|
||||
template <class T, class F>
|
||||
class LambdaIterator : public IteratorBase<T>
|
||||
class LambdaIterator : public IteratorBase<T>,
|
||||
public Composable<T, LambdaIterator<T, F>>
|
||||
{
|
||||
public:
|
||||
LambdaIterator(F &&f, size_t count) : func(std::move(f)), _count(count) {}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
@@ -12,7 +12,8 @@ namespace iter
|
||||
// I - iterator type
|
||||
// OP - type of mapper function. OP: V -> Option<T>
|
||||
template <class T, class I, class OP>
|
||||
class LimitedMap : public IteratorBase<T>
|
||||
class LimitedMap : public IteratorBase<T>,
|
||||
public Composable<T, LimitedMap<T, I, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
#include "utils/option.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
@@ -12,7 +12,7 @@ namespace iter
|
||||
// I - iterator type
|
||||
// OP - type of mapper function
|
||||
template <class T, class I, class OP>
|
||||
class Map : public IteratorBase<T>
|
||||
class Map : public IteratorBase<T>, public Composable<T, Map<T, I, OP>>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
48
include/utils/iterator/virtual_iter.hpp
Normal file
48
include/utils/iterator/virtual_iter.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "utils/iterator/composable.hpp"
|
||||
#include "utils/iterator/iterator_base.hpp"
|
||||
|
||||
namespace iter
|
||||
{
|
||||
|
||||
// Class which wraps iterator and hides it's type. It actualy does this by
|
||||
// dynamicly allocating iterator on heap.
|
||||
// T - type of return value
|
||||
template <class T>
|
||||
class Virtual : public Composable<T, Virtual<T>>
|
||||
{
|
||||
|
||||
public:
|
||||
Virtual() = delete;
|
||||
|
||||
// Virtual operation is designed to be used in chained calls which operate
|
||||
// on a
|
||||
// iterator. Virtual will in that usecase receive other iterator by value
|
||||
// and
|
||||
// std::move is a optimization for it.
|
||||
|
||||
template <class I>
|
||||
Virtual(I &&iter) : it(std::make_unique<I>(std::move(iter)))
|
||||
{
|
||||
}
|
||||
|
||||
Virtual(Virtual &&m) : it(std::move(m.it)) {}
|
||||
|
||||
~Virtual() {}
|
||||
|
||||
Option<T> next() { return it.get()->next(); }
|
||||
|
||||
Count count() { return it.get()->count(); }
|
||||
|
||||
private:
|
||||
std::unique_ptr<IteratorBase<T>> it;
|
||||
};
|
||||
|
||||
template <class I>
|
||||
auto make_virtual(I &&iter)
|
||||
{
|
||||
// Compiler cant deduce type T. decltype is here to help with it.
|
||||
return Virtual<decltype(iter.next().take())>(std::move(iter));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user