Commmit for buda.

This commit is contained in:
Kruno Tomola Fabro 2016-08-30 05:29:30 +01:00
commit ff07babeba
21 changed files with 343 additions and 111 deletions

View File

@ -407,6 +407,7 @@ set(memgraph_src_files
${src_dir}/utils/string/transform.cpp
${src_dir}/utils/string/join.cpp
${src_dir}/utils/string/file.cpp
${src_dir}/utils/iterator/iterator_base.cpp
${src_dir}/query_engine/util.cpp
${src_dir}/communication/bolt/v1/bolt.cpp
${src_dir}/communication/bolt/v1/states.cpp

View File

@ -64,8 +64,8 @@ using label_ref_t = ReferenceWrapper<const Label>;
// Original class should have Sized barrier class if it can't be Unsized.
// Sized barrier classes should:
// --Have same name as original class.
// --Inherit Sized class from common.hpp as private. Blueprint:
// class class_name: Sized<size_of_t,aligment_of_t>
// --Inherit Sized class from common.hpp as public. Blueprint:
// class class_name: public Sized<size_of_t,aligment_of_t>
// --Sized template arguments must be hardcoded numbers equal to sizeof(T) and
// alignof(T) where T is original class.
// --It should have undefined public constructor which is specialized in .cpp
@ -83,7 +83,7 @@ using label_ref_t = ReferenceWrapper<const Label>;
// --It should specify public methods which can be called on the original class.
//
// Blueprint:
// class class_name : private Sized<,>
// class class_name : public Sized<,>
// {
// public:
// template <class T>
@ -281,7 +281,8 @@ public:
void abort();
};
class VertexIterator : private Sized<8, 8>
class VertexIterator : public Sized<8, 8>,
public IteratorBase<const VertexAccessor>
{
public:
template <class T>
@ -293,11 +294,14 @@ public:
VertexIterator &operator=(const VertexIterator &other) = delete;
VertexIterator &operator=(VertexIterator &&other) = delete;
Option<const VertexAccessor> next();
Option<const VertexAccessor> next() final;
Count count() final;
};
// TODO: Find reasons of such great size ant try to decrease it.
class VertexAccessIterator : private Sized<552, 8>
class VertexAccessIterator : public Sized<560, 8>,
public IteratorBase<const VertexAccessor>
{
public:
template <class T>
@ -309,11 +313,14 @@ public:
VertexAccessIterator &operator=(const VertexAccessIterator &other) = delete;
VertexAccessIterator &operator=(VertexAccessIterator &&other) = delete;
Option<const VertexAccessor> next();
Option<const VertexAccessor> next() final;
Count count() final;
};
// TODO: Find reasons of such great size ant try to decrease it.
class EdgeAccessIterator : private Sized<552, 8>
class EdgeAccessIterator : public Sized<560, 8>,
public IteratorBase<const EdgeAccessor>
{
public:
template <class T>
@ -325,10 +332,13 @@ public:
EdgeAccessIterator &operator=(const EdgeAccessIterator &other) = delete;
EdgeAccessIterator &operator=(EdgeAccessIterator &&other) = delete;
Option<const EdgeAccessor> next();
Option<const EdgeAccessor> next() final;
Count count() final;
};
class OutEdgesIterator : private Sized<40, 8>
class OutEdgesIterator : public Sized<48, 8>,
public IteratorBase<const EdgeAccessor>
{
public:
template <class T>
@ -340,10 +350,13 @@ public:
OutEdgesIterator &operator=(const OutEdgesIterator &other) = delete;
OutEdgesIterator &operator=(OutEdgesIterator &&other) = delete;
Option<const EdgeAccessor> next();
Option<const EdgeAccessor> next() final;
Count count() final;
};
class InEdgesIterator : private Sized<56, 8>
class InEdgesIterator : public Sized<64, 8>,
public IteratorBase<const EdgeAccessor>
{
public:
template <class T>
@ -355,10 +368,12 @@ public:
InEdgesIterator &operator=(const InEdgesIterator &other) = delete;
InEdgesIterator &operator=(InEdgesIterator &&other) = delete;
Option<const EdgeAccessor> next();
Option<const EdgeAccessor> next() final;
Count count() final;
};
class EdgeIterator : private Sized<8, 8>
class EdgeIterator : public Sized<8, 8>, public IteratorBase<const EdgeAccessor>
{
public:
template <class T>
@ -370,7 +385,9 @@ public:
EdgeIterator &operator=(const EdgeIterator &other) = delete;
EdgeIterator &operator=(EdgeIterator &&other) = delete;
Option<const EdgeAccessor> next();
Option<const EdgeAccessor> next() final;
Count count() final;
};
class VertexPropertyKey : private Sized<8, 8>

View File

@ -121,6 +121,18 @@ protected:
"Border class aligment mismatch");
}
public:
typename std::aligned_storage<size_B, alignment_B>::type &_data_ref()
{
return data;
}
typename std::aligned_storage<size_B, alignment_B>::type const &
_data_ref_const() const
{
return data;
}
private:
// Here is the aligned storage which imitates size and aligment of object of
// original class from memgraph.

View File

@ -12,6 +12,8 @@
#include "storage/edge_x_vertex.hpp"
#include "storage/label/label.hpp"
// This is the place for imports from memgraph .cpp
// **************************** HELPER DEFINES *******************************//
// Creates 8 functions for transformation of refereces between types x and y.
// Where x is a border type.
@ -26,6 +28,21 @@
y *trans(x *l) { return ptr_as<y>(l); } \
y const *trans(x const *l) { return ptr_as<y const>(l); }
// Creates 4 functions for transformation of refereces between types x and y.
// Where x is a sized border type.
// DANGEROUS
#define TRANSFORM_REF_SIZED(x, y) \
y &trans(x &l) { return ref_as<y>(l._data_ref()); } \
y const &trans(x const &l) \
{ \
return ref_as<y const>(l._data_ref_const()); \
} \
y *trans(x *l) { return ptr_as<y>(&(l->_data_ref())); } \
y const *trans(x const *l) \
{ \
return ptr_as<y const>(&(l->_data_ref_const())); \
}
// Creates 8 functions for transformation of refereces between types x and y.
// Where both x and y are templates over T. Where x is a border type.
// DANGEROUS
@ -158,14 +175,16 @@ TRANSFORM_REF(VertexPropertyKey,
::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
TRANSFORM_REF(EdgePropertyKey,
::EdgePropertyFamily::PropertyType::PropertyFamilyKey);
TRANSFORM_REF(VertexIterator,
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
TRANSFORM_REF(EdgeIterator,
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
TRANSFORM_REF(VertexAccessIterator, vertex_access_iterator_t);
TRANSFORM_REF(EdgeAccessIterator, edge_access_iterator_t);
TRANSFORM_REF(OutEdgesIterator, out_edge_iterator_t);
TRANSFORM_REF(InEdgesIterator, in_edge_iterator_t);
// ITERATORS
TRANSFORM_REF_SIZED(VertexIterator,
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
TRANSFORM_REF_SIZED(EdgeIterator,
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
TRANSFORM_REF_SIZED(VertexAccessIterator, vertex_access_iterator_t);
TRANSFORM_REF_SIZED(EdgeAccessIterator, edge_access_iterator_t);
TRANSFORM_REF_SIZED(OutEdgesIterator, out_edge_iterator_t);
TRANSFORM_REF_SIZED(InEdgesIterator, in_edge_iterator_t);
template <class T>
TRANSFORM_REF_TEMPLATED(VertexIndex<T>, VertexIndexBase<T>);
@ -193,21 +212,22 @@ TRANSFORM_VALUE(EdgePropertyKey,
TRANSFORM_VALUE(VertexPropertyKey,
::VertexPropertyFamily::PropertyType::PropertyFamilyKey);
TRANSFORM_VALUE_ONE(VertexAccessIterator, vertex_access_iterator_t);
MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t);
// MOVE_CONSTRUCTOR_FORCED(VertexAccessIterator, vertex_access_iterator_t);
TRANSFORM_VALUE_ONE(EdgeAccessIterator, edge_access_iterator_t);
MOVE_CONSTRUCTOR_FORCED(EdgeAccessIterator, edge_access_iterator_t);
// MOVE_CONSTRUCTOR_FORCED(EdgeAccessIterator, edge_access_iterator_t);
TRANSFORM_VALUE_ONE(OutEdgesIterator, out_edge_iterator_t);
MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
// MOVE_CONSTRUCTOR_FORCED(OutEdgesIterator, out_edge_iterator_t);
TRANSFORM_VALUE_ONE(InEdgesIterator, in_edge_iterator_t);
MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
// MOVE_CONSTRUCTOR_FORCED(InEdgesIterator, in_edge_iterator_t);
TRANSFORM_VALUE_ONE(VertexIterator,
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
MOVE_CONSTRUCTOR_FORCED(VertexIterator,
std::unique_ptr<IteratorBase<const ::VertexAccessor>>);
// MOVE_CONSTRUCTOR_FORCED(VertexIterator,
// std::unique_ptr<IteratorBase<const
// ::VertexAccessor>>);
TRANSFORM_VALUE_ONE(EdgeIterator,
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
// MOVE_CONSTRUCTOR_FORCED(EdgeIterator,
// std::unique_ptr<IteratorBase<const ::EdgeAccessor>>);
template <class T>
TRANSFORM_VALUE_ONE_RAW(

View File

@ -62,6 +62,8 @@ public:
~AccessorBase() {}
size_t size() { return accessor.size(); };
list_it begin() { return accessor.begin(); }
list_it_con begin() const { return accessor.cbegin(); }

View File

@ -281,6 +281,8 @@ public:
ConstIterator cend() { return ConstIterator(); }
std::size_t size() { return count.load(std::memory_order_consume); }
private:
std::atomic<std::size_t> count{0};
std::atomic<Node *> head{nullptr};

View File

@ -4,6 +4,7 @@
#include <map>
#include "barrier/barrier.hpp"
#include "utils/iterator/iterator_base.cpp"
using namespace std;
@ -157,11 +158,8 @@ auto load_queries(Db &db)
auto match_all_nodes = [&db](const properties_t &args) {
DbAccessor t(db);
iter::for_all(t.vertex_access(), [&](auto vertex) {
if (vertex.fill()) {
cout << vertex.id() << endl;
}
});
t.vertex_access().fill().for_all(
[&](auto vertex) { cout << vertex.id() << endl; });
return t.commit();
};
@ -174,8 +172,8 @@ auto load_queries(Db &db)
auto prop_key = t.vertex_property_key("name", Flags::String);
cout << "VERTICES" << endl;
iter::for_all(label.index().for_range(t),
[&](auto a) { cout << a.at(prop_key) << endl; });
label.index().for_range(t).for_all(
[&](auto a) { cout << a.at(prop_key) << endl; });
return t.commit();
};
@ -184,11 +182,7 @@ auto load_queries(Db &db)
auto match_all_delete = [&db](const properties_t &args) {
DbAccessor t(db);
iter::for_all(t.vertex_access(), [&](auto a) {
if (a.fill()) {
a.remove();
}
});
t.vertex_access().fill().for_all([&](auto a) { a.remove(); });
return t.commit();
};
@ -199,11 +193,7 @@ auto load_queries(Db &db)
auto &label = t.label_find_or_create("LABEL");
iter::for_all(label.index().for_range(t), [&](auto a) {
if (a.fill()) {
a.remove();
}
});
label.index().for_range(t).for_all([&](auto a) { a.remove(); });
return t.commit();
};
@ -238,11 +228,7 @@ auto load_queries(Db &db)
auto match_edge_all_delete = [&db](const properties_t &args) {
DbAccessor t(db);
iter::for_all(t.edge_access(), [&](auto a) {
if (a.fill()) {
a.remove();
}
});
t.edge_access().fill().for_all([&](auto a) { a.remove(); });
return t.commit();
};
@ -253,26 +239,46 @@ auto load_queries(Db &db)
auto &type = t.type_find_or_create("TYPE");
iter::for_all(type.index().for_range(t), [&](auto a) {
if (a.fill()) {
a.remove();
}
});
type.index().for_range(t).for_all([&](auto a) { a.remove(); });
return t.commit();
};
// MATCH (n)-[:TYPE]->(m) WHERE ID(n) = id RETURN m
auto match_type_id_return = [&db](const properties_t &args) {
auto match_id_type_return = [&db](const properties_t &args) {
DbAccessor t(db);
auto &type = t.type_find_or_create("TYPE");
auto ov = t.vertex_find(args[0]->as<Int64>().value);
if (!option_fill(ov)) return t.commit(), false;
auto v = ov.take();
auto resoults = iter::make_f`
auto results = v.out().fill().type(type).to();
return t.commit();
// Example of Print resoult.
// results.for_all([&](auto va) {
// va is VertexAccessor
// PRINT
// });
return t.commit();
};
// MATCH (n)-[:TYPE]->(m) WHERE n.name = "kruno" RETURN m
auto match_name_type_return = [&db](const properties_t &args) {
DbAccessor t(db);
auto &type = t.type_find_or_create("TYPE");
auto it_type = type.index().for_range(t);
auto it_vertex = t.vertex_access();
// if(it_type.count().max>it_vertex.count().max){
//
// }
return t.commit();
};
// Blueprint:
@ -299,6 +305,7 @@ auto load_queries(Db &db)
queries[6963549500479100885u] = match_edge_id_delete;
queries[14897166600223619735u] = match_edge_all_delete;
queries[16888549834923624215u] = match_edge_type_delete;
queries[11675960684124428508u] = match_id_type_return;
return queries;
}

View File

@ -27,6 +27,8 @@ public:
void clear() { edges.clear(); }
std::size_t size() { return edges.size(); }
private:
std::vector<EdgeRecord *> edges;
};

View File

@ -28,6 +28,8 @@ public:
void clear() { edges.clear(); }
std::size_t size() { return edges.size(); }
private:
RhHashMultiMap<VertexRecord *, EdgeRecord> edges;
};

View File

@ -0,0 +1,21 @@
#pragma once
// Represents number of to be returned elements from iterator. Where acutal
// number is probably somwhere in [min,max].
class Count
{
public:
Count(size_t exact) : min(exact), max(exact) {}
Count(size_t min, size_t max) : min(min), max(max) {}
Count &min_zero()
{
min = 0;
return *this;
}
size_t min;
size_t max;
};

View File

@ -6,12 +6,11 @@
namespace iter
{
// Class which filters values returned by I iterator into value of type T with
// OP
// function.
// Class which filters values T returned by I iterator if OP returns true for
// them.
// T - type of return value
// I - iterator type
// OP - type of mapper function
// OP - type of filter function. OP: T& -> bool
template <class T, class I, class OP>
class Filter : public IteratorBase<T>
{
@ -25,30 +24,32 @@ public:
// std::move is a optimization for it.
Filter(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
Filter(Filter &&m) : iter(std::move(m.iter)), op(std::move(m.op)) {}
~Filter() final {}
// Return values for which filter return true.
Option<T> next() final
{
auto item = iter.next();
if (item.is_present()) {
return Option<T>(op(item.take()));
} else {
return Option<T>();
}
auto item = Option<T>();
do {
item = iter.next();
if (!item.is_present()) {
return Option<T>();
}
} while (!op(item.get()));
return std::move(item);
}
Count count() final { return iter.count().min_zero(); }
private:
I iter;
OP op;
};
template <class I, class OP>
auto make_map(I &&iter, OP &&op)
auto make_filter(I &&iter, OP &&op)
{
// Compiler cant deduce type T. decltype is here to help with it.
return Filter<decltype(op(iter.next().take())), I, OP>(std::move(iter),
std::move(op));
return Filter<decltype(iter.next().take()), I, OP>(std::move(iter),
std::move(op));
}
}

View File

@ -1,6 +1,8 @@
#pragma once
#include "utils/iterator/accessor.hpp"
#include "utils/iterator/count.hpp"
#include "utils/iterator/filter.hpp"
#include "utils/iterator/for_all.hpp"
#include "utils/iterator/iterator_accessor.hpp"
#include "utils/iterator/iterator_base.hpp"

View File

@ -17,12 +17,13 @@ public:
IteratorAccessor() = delete;
IteratorAccessor(A &&acc)
: begin(std::move(acc.begin())), acc(std::forward<A>(acc))
: begin(std::move(acc.begin())), acc(std::forward<A>(acc)), returned(0)
{
}
IteratorAccessor(IteratorAccessor &&other)
: begin(std::move(other.begin)), acc(std::forward<A>(other.acc))
: begin(std::move(other.begin)), acc(std::forward<A>(other.acc)),
returned(other.returned)
{
}
@ -37,15 +38,27 @@ public:
if (begin != acc.end()) {
auto ret = Option<T>(&(*(begin.operator->())));
begin++;
returned++;
return ret;
} else {
return Option<T>();
}
}
Count count() final
{
auto size = acc.size();
if (size > returned) {
return Count(0);
} else {
return Count(size - returned);
}
}
private:
I begin;
A acc;
size_t returned;
};
// TODO: Join to make functions into one

View File

@ -1,7 +1,10 @@
#pragma once
#include "utils/iterator/count.hpp"
#include "utils/option.hpp"
class EdgeType;
// Base iterator for next() kind iterator.
// T - type of return value
template <class T>
@ -11,4 +14,26 @@ public:
virtual ~IteratorBase(){};
virtual Option<T> next() = 0;
virtual Count count() { return Count(0, ~((size_t)0)); }
template <class OP>
auto map(OP &&op);
template <class OP>
auto filter(OP &&op);
// Maps with call to method to() and filters with call to fill.
auto to();
// Filters with call to method fill()
auto fill();
// Filters with type
template <class TYPE>
auto type(TYPE const &type);
// For all items calls OP.
template <class OP>
void for_all(OP &&op);
};

View File

@ -11,26 +11,36 @@ template <class T, class F>
class LambdaIterator : public IteratorBase<T>
{
public:
LambdaIterator(F &&f) : func(std::move(f)) {}
LambdaIterator(F &&f, size_t count) : func(std::move(f)), _count(count) {}
LambdaIterator(LambdaIterator &&other) : func(std::move(other.func)) {}
LambdaIterator(LambdaIterator &&other)
: func(std::move(other.func)), _count(other._count)
{
}
~LambdaIterator() final {}
Option<T> next() final { return func(); }
Option<T> next() final
{
_count = _count > 0 ? _count - 1 : 0;
return func();
}
Count count() final { return Count(_count); }
private:
F func;
size_t _count;
};
// Wraps lambda which returns options as an iterator.
template <class F>
auto make_iterator(F &&f)
auto make_iterator(F &&f, size_t count)
{
// Because function isn't receving or in any way using type T from
// FunctionIterator compiler can't deduce it thats way there is decltype in
// construction of FunctionIterator. Resoulting type of iter.next().take()
// is T.
return LambdaIterator<decltype(f().take()), F>(std::move(f));
return LambdaIterator<decltype(f().take()), F>(std::move(f), count);
}
}

View File

@ -37,6 +37,8 @@ public:
}
}
Count count() final { return iter.count(); }
private:
I iter;
OP op;

View File

@ -0,0 +1,29 @@
#pragma once
#include "storage/vertex_accessor.hpp"
#include "utils/iterator/iterator.hpp"
#include "utils/option.hpp"
namespace query_help
{
template <class A>
bool fill(A &a)
{
return a.fill();
}
};
// Base iterator for next() kind iterator.
// Vertex::Accessor - type of return value
template <>
class IteratorBase<Vertex::Accessor>
{
public:
virtual Option<Vertex::Accessor> next() = 0;
auto fill()
{
return iter::make_filter(std::move(*this), query_help::fill);
}
};

View File

@ -437,6 +437,8 @@ Option<const VertexAccessor> VertexIterator::next()
return HALF_CALL(get()->next()).map<const VertexAccessor>();
}
Count VertexIterator::count() { return HALF_CALL(get()->count()); }
// ************************* EdgeIterator
DESTRUCTOR(EdgeIterator, unique_ptr);
@ -445,6 +447,8 @@ Option<const EdgeAccessor> EdgeIterator::next()
return HALF_CALL(get()->next()).map<const EdgeAccessor>();
}
Count EdgeIterator::count() { return HALF_CALL(get()->count()); }
// ************************* OutEdgesIterator
DESTRUCTOR(OutEdgesIterator, out_edge_iterator_t);
@ -453,6 +457,8 @@ Option<const EdgeAccessor> OutEdgesIterator::next()
return HALF_CALL(next()).map<const EdgeAccessor>();
}
Count OutEdgesIterator::count() { return HALF_CALL(count()); }
// ************************* InEdgesIterator
DESTRUCTOR(InEdgesIterator, in_edge_iterator_t);
@ -461,6 +467,8 @@ Option<const EdgeAccessor> InEdgesIterator::next()
return HALF_CALL(next()).map<const EdgeAccessor>();
}
Count InEdgesIterator::count() { return HALF_CALL(count()); }
// ************************* VertexAccessIterator
DESTRUCTOR(VertexAccessIterator, vertex_access_iterator_t);
@ -469,6 +477,8 @@ Option<const VertexAccessor> VertexAccessIterator::next()
return HALF_CALL(next()).map<const VertexAccessor>();
}
Count VertexAccessIterator::count() { return HALF_CALL(count()); }
// ************************* EdgeAccessIterator
DESTRUCTOR(EdgeAccessIterator, edge_access_iterator_t);
@ -477,6 +487,8 @@ Option<const EdgeAccessor> EdgeAccessIterator::next()
return HALF_CALL(next()).map<const EdgeAccessor>();
}
Count EdgeAccessIterator::count() { return HALF_CALL(count()); }
// ************************* VertexPropertyKey
DESTRUCTOR(VertexPropertyKey, PropertyFamilyKey);

View File

@ -46,22 +46,26 @@ auto NonUniqueUnorderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
Border<K> from_v,
Border<K> to_v)
{
return iter::make_iterator([
it = list.cbegin(), end = list.cend(), from = from_v, to = to_v, t = t_v
]() mutable->auto {
while (it != end) {
const IndexRecord<T, K> &r = *it;
if (from < r.key && to > r.key &&
r.is_valid(t.db_transaction.trans)) {
const typename T::accessor_t acc = r.access(t.db_transaction);
return iter::make_iterator(
[
it = list.cbegin(), end = list.cend(), from = from_v, to = to_v,
t = t_v
]() mutable->auto {
while (it != end) {
const IndexRecord<T, K> &r = *it;
if (from < r.key && to > r.key &&
r.is_valid(t.db_transaction.trans)) {
const typename T::accessor_t acc =
r.access(t.db_transaction);
it++;
return make_option(std::move(acc));
}
it++;
return make_option(std::move(acc));
}
it++;
}
return Option<const typename T::accessor_t>();
});
return Option<const typename T::accessor_t>();
},
list.size());
}
template <class T, class K>

View File

@ -64,23 +64,28 @@ auto UniqueOrderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
} else {
assert(this->order() != None);
}
// TODO: determine size on fact of border size.
auto size = acc.size();
return iter::make_iterator([
it = std::move(begin), b_end = std::move(end), t = t_v,
hold_acc = std::move(acc)
]() mutable->auto {
while (b_end >= it->key) {
const IndexRecord<T, K> &r = *it;
if (r.is_valid(t.db_transaction.trans)) {
const typename T::accessor_t acc = r.access(t.db_transaction);
return iter::make_iterator(
[
it = std::move(begin), b_end = std::move(end), t = t_v,
hold_acc = std::move(acc)
]() mutable->auto {
while (b_end >= it->key) {
const IndexRecord<T, K> &r = *it;
if (r.is_valid(t.db_transaction.trans)) {
const typename T::accessor_t acc =
r.access(t.db_transaction);
it++;
return make_option(std::move(acc));
}
it++;
return make_option(std::move(acc));
}
it++;
}
return Option<const typename T::accessor_t>();
});
return Option<const typename T::accessor_t>();
},
size);
}
template <class T, class K>

View File

@ -0,0 +1,43 @@
#include "utils/iterator/iterator.hpp"
template <class T>
template <class OP>
auto IteratorBase<T>::map(OP &&op)
{
return iter::make_map<decltype(std::move(*this)), OP>(std::move(*this),
std::move(op));
}
template <class T>
template <class OP>
auto IteratorBase<T>::filter(OP &&op)
{
return iter::make_filter<decltype(std::move(*this)), OP>(std::move(*this),
std::move(op));
}
template <class T>
auto IteratorBase<T>::to()
{
return map([](auto er) { return er.to(); }).fill();
}
template <class T>
auto IteratorBase<T>::fill()
{
return filter([](auto &ra) { return ra.fill(); });
}
template <class T>
template <class TYPE>
auto IteratorBase<T>::type(TYPE const &type)
{
return filter([&](auto &ra) { return ra.edge_type() == type; });
}
template <class T>
template <class OP>
void IteratorBase<T>::for_all(OP &&op)
{
iter::for_all(std::move(*this), std::move(op));
}