#pragma once #ifdef BARRIER #include "barrier/barrier.hpp" // This is the place for imports from memgraph .hpp #include "communication/bolt/v1/serialization/bolt_serializer.hpp" #include "communication/bolt/v1/serialization/record_stream.hpp" #include "database/db.hpp" #include "database/db_accessor.hpp" #include "io/network/socket.hpp" #include "storage/edge_type/edge_type.hpp" #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. // DANGEROUS #define TRANSFORM_REF(x, y) \ x &trans(y &l) { return ref_as(l); } \ x const &trans(y const &l) { return ref_as(l); } \ y &trans(x &l) { return ref_as(l); } \ y const &trans(x const &l) { return ref_as(l); } \ x *trans(y *l) { return ptr_as(l); } \ x const *trans(y const *l) { return ptr_as(l); } \ y *trans(x *l) { return ptr_as(l); } \ y const *trans(x const *l) { return ptr_as(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(l._data_ref()); } \ y const &trans(x const &l) \ { \ return ref_as(l._data_ref_const()); \ } \ y *trans(x *l) { return ptr_as(&(l->_data_ref())); } \ y const *trans(x const *l) \ { \ return ptr_as(&(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 #define TRANSFORM_REF_TEMPLATED(x, y) \ x &trans(y &l) { return ref_as(l); } \ template \ x const &trans(y const &l) \ { \ return ref_as(l); \ } \ template \ y &trans(x &l) \ { \ return ref_as(l); \ } \ template \ y const &trans(x const &l) \ { \ return ref_as(l); \ } \ template \ x *trans(y *l) \ { \ return ptr_as(l); \ } \ template \ const x *trans(const y *l) \ { \ return ptr_as(l); \ } \ template \ y *trans(x *l) \ { \ return ptr_as(l); \ } \ template \ const y *trans(const x *l) \ { \ return ptr_as(l); \ } // For certain classes trans evaluates into ref which doesnt work for Sized // constructor. This Move forces type y. // DANGEROUS #define MOVE_CONSTRUCTOR_FORCED(x, y) \ x::x(x &&other) : Sized(value_as(std::move(other))) {} // Creates constructor x(y) where x is border type and y shpuld be his original // type. // DANGEROUS #define VALID_CONSTRUCTION(x, y) \ template <> \ barrier::x::x(y &&d) : Sized(std::move(d)) \ { \ } // Creates const constructor x(y) where x is border type and y shpuld be his // original type. // DANGEROUS #define VALID_CONSTRUCTION_CONST(x, y) \ template <> \ barrier::x::x(y const &&d) : Sized(std::move(d)) \ { \ } // Creates value transformation function from original type y to border type x. // DANGEROUS #define TRANSFORM_VALUE_ONE_RAW(x, y) \ x trans(y &&d) { return x(std::move(d)); } // Creates value transformation function and constructor from original type y to // border type x. // DANGEROUS #define TRANSFORM_VALUE_ONE(x, y) \ VALID_CONSTRUCTION(x, y) \ x trans(y &&d) { return x(std::move(d)); } // Creates value transformation functions and constructor between border type x // and original type y. Only mutable values. // DANGEROUS #define TRANSFORM_VALUE_MUT(x, y) \ TRANSFORM_VALUE_ONE(x, y) \ y trans(x &&d) { return value_as(std::move(d)); } // Creates value transformation functions and constructors between border type x // and original type y. // DANGEROUS #define TRANSFORM_VALUE(x, y) \ TRANSFORM_VALUE_MUT(x, y) \ VALID_CONSTRUCTION_CONST(x, y) \ const x trans(const y &&d) { return x(std::move(d)); } \ const y trans(const x &&d) { return value_as(std::move(d)); } // Duplicates given x to call y with x and ::x #define DUP(x, y) y(x, ::x) // ********************** TYPES OF AUTO using vertex_access_iterator_t = decltype(((::DbAccessor *)(std::nullptr_t()))->vertex_access()); using edge_access_iterator_t = decltype(((::DbAccessor *)(std::nullptr_t()))->edge_access()); using out_edge_iterator_t = decltype(((::VertexAccessor *)(std::nullptr_t()))->out()); using in_edge_iterator_t = decltype(((::VertexAccessor *)(std::nullptr_t()))->in()); // ******************** OVERLOADED trans FUNCTIONS. // This enclosure is the only dangerous part of barrier except of Sized class in // common.hpp namespace barrier { // Blueprint for valid transformation of references: // TRANSFORM_REF(, ::); // template TRANSFORM_REF_TEMPLATED(,::); // TODO: Strongest assurance that evertyhing is correct is for all of following // transformation to use DUP for defining theres transformation. This would mean // that names of classes exported in barrier and names from real class in // database are equal. // ***************** TRANSFORMS of reference and pointers DUP(Label, TRANSFORM_REF); DUP(EdgeType, TRANSFORM_REF); DUP(VertexPropertyFamily, TRANSFORM_REF); DUP(EdgePropertyFamily, TRANSFORM_REF); DUP(VertexAccessor, TRANSFORM_REF); DUP(EdgeAccessor, TRANSFORM_REF); DUP(Db, TRANSFORM_REF); DUP(DbAccessor, TRANSFORM_REF); TRANSFORM_REF(std::vector, std::vector<::label_ref_t>); TRANSFORM_REF(VertexPropertyKey, ::VertexPropertyFamily::PropertyType::PropertyFamilyKey); TRANSFORM_REF(EdgePropertyKey, ::EdgePropertyFamily::PropertyType::PropertyFamilyKey); TRANSFORM_REF(VertexStoredProperty, ::StoredProperty); TRANSFORM_REF(EdgeStoredProperty, ::StoredProperty); // ITERATORS TRANSFORM_REF(VertexIterator, ::iter::Virtual); TRANSFORM_REF(EdgeIterator, ::iter::Virtual); 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); template TRANSFORM_REF_TEMPLATED(VertexIndex, VertexIndexBase); template TRANSFORM_REF_TEMPLATED(EdgeIndex, EdgeIndexBase); template TRANSFORM_REF_TEMPLATED(RecordStream, ::bolt::RecordStream); template TRANSFORM_REF_TEMPLATED( VertexPropertyType, ::VertexPropertyFamily::PropertyType::PropertyTypeKey); template TRANSFORM_REF_TEMPLATED(EdgePropertyType, ::EdgePropertyFamily::PropertyType::PropertyTypeKey); // ****************** TRANSFORMS of value // Blueprint for valid transformation of value: // TRANSFORM_VALUE(, ::); DUP(VertexAccessor, TRANSFORM_VALUE); DUP(EdgeAccessor, TRANSFORM_VALUE); TRANSFORM_VALUE(EdgePropertyKey, ::EdgePropertyFamily::PropertyType::PropertyFamilyKey); TRANSFORM_VALUE(VertexPropertyKey, ::VertexPropertyFamily::PropertyType::PropertyFamilyKey); TRANSFORM_VALUE_ONE(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); TRANSFORM_VALUE_ONE(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); TRANSFORM_VALUE_ONE(VertexIterator, ::iter::Virtual); MOVE_CONSTRUCTOR_FORCED(VertexIterator, ::iter::Virtual); TRANSFORM_VALUE_ONE(EdgeIterator, ::iter::Virtual); MOVE_CONSTRUCTOR_FORCED(EdgeIterator, ::iter::Virtual); template TRANSFORM_VALUE_ONE_RAW( VertexPropertyType, ::VertexPropertyFamily::PropertyType::PropertyTypeKey); template TRANSFORM_VALUE_ONE_RAW(EdgePropertyType, ::EdgePropertyFamily::PropertyType::PropertyTypeKey) template TRANSFORM_VALUE_ONE_RAW(RecordStream, ::bolt::RecordStream) // ********************* SPECIAL CONSTRUCTORS #define VertexPropertyType_constructor(x) \ template <> \ template <> \ VertexPropertyType::VertexPropertyType( \ ::VertexPropertyFamily::PropertyType::PropertyTypeKey &&d) \ : Sized(std::move(d)) \ { \ } INSTANTIATE_FOR_PROPERTY(VertexPropertyType_constructor); #define EdgePropertyType_constructor(x) \ template <> \ template <> \ EdgePropertyType::EdgePropertyType( \ ::EdgePropertyFamily::PropertyType::PropertyTypeKey &&d) \ : Sized(std::move(d)) \ { \ } INSTANTIATE_FOR_PROPERTY(EdgePropertyType_constructor); DbAccessor::DbAccessor(Db &db) : Sized(::DbAccessor(trans(db))) {} } #endif