Add edge and vertex to TypedValue

Summary:
Merge branch 'dev' into mg_full_typed_value

Add Path and Map to TypedValue

Reviewers: buda

Reviewed By: buda

Subscribers: pullbot

Differential Revision: https://phabricator.memgraph.io/D80
This commit is contained in:
Mislav Bradac 2017-03-01 18:05:19 +01:00
parent 80c266ce21
commit 1125331649
2 changed files with 140 additions and 32 deletions

View File

@ -12,32 +12,26 @@ TypedValue::TypedValue(const PropertyValue& value) {
case PropertyValue::Type::Null:
type_ = Type::Null;
return;
case PropertyValue::Type::Bool:
type_ = Type::Bool;
bool_v = value.Value<bool>();
return;
case PropertyValue::Type::Int:
type_ = Type::Int;
int_v = value.Value<int>();
return;
case PropertyValue::Type::Double:
type_ = Type::Double;
double_v = value.Value<double>();
case PropertyValue::Type::String:
type_ = Type::String;
new (&string_v) std::string(value.Value<std::string>());
case PropertyValue::Type::List:
type_ = Type::List;
auto vec = value.Value<std::vector<PropertyValue>>();
new (&list_v) std::vector<TypedValue>(vec.begin(), vec.end());
return;
}
permanent_fail("Unsupported PropertyValue::Type");
}
@ -56,6 +50,8 @@ TypedValue::operator PropertyValue() const {
case TypedValue::Type::List:
return PropertyValue(
std::vector<PropertyValue>(list_v.begin(), list_v.end()));
default:
permanent_fail("Unsupported PropertyValue::Type");
}
permanent_fail("Unsupported PropertyValue::Type");
}
@ -68,13 +64,6 @@ bool TypedValue::Value<bool>() const {
return bool_v;
}
template <>
std::string TypedValue::Value<std::string>() const {
debug_assert(type_ == TypedValue::Type::String,
"Incompatible template param and type");
return string_v;
}
template <>
int TypedValue::Value<int>() const {
debug_assert(type_ == TypedValue::Type::Int,
@ -89,6 +78,13 @@ double TypedValue::Value<double>() const {
return double_v;
}
template <>
std::string TypedValue::Value<std::string>() const {
debug_assert(type_ == TypedValue::Type::String,
"Incompatible template param and type");
return string_v;
}
template <>
std::vector<TypedValue> TypedValue::Value<std::vector<TypedValue>>() const {
debug_assert(type_ == TypedValue::Type::List,
@ -96,32 +92,66 @@ std::vector<TypedValue> TypedValue::Value<std::vector<TypedValue>>() const {
return list_v;
}
template <>
std::map<std::string, TypedValue>
TypedValue::Value<std::map<std::string, TypedValue>>() const {
debug_assert(type_ == TypedValue::Type::Map,
"Incompatible template param and type");
return map_v;
}
template <>
VertexAccessor TypedValue::Value<VertexAccessor>() const {
debug_assert(type_ == TypedValue::Type::Vertex,
"Incompatible template param and type");
return vertex_v;
}
template <>
EdgeAccessor TypedValue::Value<EdgeAccessor>() const {
debug_assert(type_ == TypedValue::Type::Edge,
"Incompatible template param and type");
return edge_v;
}
template <>
Path TypedValue::Value<Path>() const {
debug_assert(type_ == TypedValue::Type::Path,
"Incompatible template param and type");
return path_v;
}
TypedValue::TypedValue(const TypedValue& other) : type_(other.type_) {
switch (other.type_) {
case TypedValue::Type::Null:
return;
case TypedValue::Type::Bool:
this->bool_v = other.bool_v;
return;
case TypedValue::Type::String:
new (&string_v) std::string(other.string_v);
return;
case Type::Int:
this->int_v = other.int_v;
return;
case Type::Double:
this->double_v = other.double_v;
return;
case TypedValue::Type::String:
new (&string_v) std::string(other.string_v);
return;
case Type::List:
new (&list_v) std::vector<TypedValue>(other.list_v);
return;
case Type::Map:
new (&map_v) std::map<std::string, TypedValue>(other.map_v);
return;
case Type::Vertex:
new (&vertex_v) VertexAccessor(other.vertex_v);
return;
case Type::Edge:
new (&edge_v) EdgeAccessor(other.edge_v);
return;
case Type::Path:
new (&path_v) Path(other.path_v);
}
permanent_fail("Unsupported TypedValue::Type");
}
@ -131,14 +161,22 @@ std::ostream& operator<<(std::ostream& os, const TypedValue::Type type) {
return os << "null";
case TypedValue::Type::Bool:
return os << "bool";
case TypedValue::Type::String:
return os << "string";
case TypedValue::Type::Int:
return os << "int";
case TypedValue::Type::Double:
return os << "double";
case TypedValue::Type::String:
return os << "string";
case TypedValue::Type::List:
return os << "list";
case TypedValue::Type::Map:
return os << "map";
case TypedValue::Type::Vertex:
return os << "vertex";
case TypedValue::Type::Edge:
return os << "edge";
case TypedValue::Type::Path:
return os << "path";
}
permanent_fail("Unsupported TypedValue::Type");
}
@ -149,18 +187,30 @@ std::ostream& operator<<(std::ostream& os, const TypedValue& value) {
return os << "Null";
case TypedValue::Type::Bool:
return os << (value.Value<bool>() ? "true" : "false");
case TypedValue::Type::String:
return os << value.Value<std::string>();
case TypedValue::Type::Int:
return os << value.Value<int>();
case TypedValue::Type::Double:
return os << value.Value<double>();
case TypedValue::Type::String:
return os << value.Value<std::string>();
case TypedValue::Type::List:
os << "[";
for (const auto& x : value.Value<std::vector<TypedValue>>()) {
os << x << ",";
}
return os << "]";
case TypedValue::Type::Map:
os << "{";
for (const auto& x : value.Value<std::map<std::string, TypedValue>>()) {
os << x.first << ": " << x.second << ",";
}
return os << "}";
case TypedValue::Type::Vertex:
return os << value.Value<VertexAccessor>();
case TypedValue::Type::Edge:
return os << value.Value<EdgeAccessor>();
case TypedValue::Type::Path:
return os << value.Value<Path>();
}
permanent_fail("Unsupported PropertyValue::Type");
}
@ -176,18 +226,30 @@ TypedValue& TypedValue::operator=(const TypedValue& other) {
case TypedValue::Type::Bool:
this->bool_v = other.bool_v;
return *this;
case TypedValue::Type::String:
new (&string_v) std::string(other.string_v);
return *this;
case TypedValue::Type::Int:
this->int_v = other.int_v;
return *this;
case TypedValue::Type::Double:
this->double_v = other.double_v;
return *this;
case TypedValue::Type::String:
new (&string_v) std::string(other.string_v);
return *this;
case TypedValue::Type::List:
new (&list_v) std::vector<TypedValue>(other.list_v);
return *this;
case TypedValue::Type::Map:
new (&map_v) std::map<std::string, TypedValue>(other.map_v);
return *this;
case TypedValue::Type::Vertex:
new (&vertex_v) VertexAccessor(other.vertex_v);
return *this;
case TypedValue::Type::Edge:
new (&edge_v) EdgeAccessor(other.edge_v);
return *this;
case TypedValue::Type::Path:
new (&path_v) Path(other.path_v);
return *this;
}
}
permanent_fail("Unsupported TypedValue::Type");
@ -216,6 +278,19 @@ TypedValue::~TypedValue() {
using namespace std;
list_v.~vector<TypedValue>();
return;
case Type::Map:
using namespace std;
map_v.~map<std::string, TypedValue>();
return;
case Type::Vertex:
vertex_v.~VertexAccessor();
return;
case Type::Edge:
edge_v.~EdgeAccessor();
return;
case Type::Path:
path_v.~Path();
return;
}
permanent_fail("Unsupported TypedValue::Type");
}

View File

@ -4,11 +4,17 @@
#include <memory>
#include <string>
#include <vector>
#include <map>
#include "utils/exceptions/stacktrace_exception.hpp"
#include "utils/total_ordering.hpp"
#include "utils/underlying_cast.hpp"
#include "storage/property_value.hpp"
#include "storage/edge_accessor.hpp"
#include "storage/vertex_accessor.hpp"
#include "traversal/path.hpp"
typedef traversal_template::Path<VertexAccessor, EdgeAccessor> Path;
/**
* Encapsulation of a value and it's type encapsulated in a class that has no
@ -24,7 +30,18 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> {
public:
/** A value type. Each type corresponds to exactly one C++ type */
enum class Type : unsigned { Null, String, Bool, Int, Double, List };
enum class Type : unsigned {
Null,
Bool,
Int,
Double,
String,
List,
Map,
Vertex,
Edge,
Path
};
// single static reference to Null, used whenever Null should be returned
static const TypedValue Null;
@ -37,7 +54,7 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> {
// conversion function to PropertyValue
operator PropertyValue() const;
/// constructors for non-primitive types (shared pointers)
/// constructors for non-primitive types
TypedValue(const std::string& value) : type_(Type::String) {
new (&string_v) std::string(value);
}
@ -47,6 +64,17 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> {
TypedValue(const std::vector<TypedValue>& value) : type_(Type::List) {
new (&list_v) std::vector<TypedValue>(value);
}
TypedValue(const std::map<std::string, TypedValue>& value)
: type_(Type::Map) {
new (&map_v) std::map<std::string, TypedValue>(value);
}
TypedValue(const VertexAccessor& vertex) : type_(Type::Vertex) {
new (&vertex_v) VertexAccessor(vertex);
}
TypedValue(const EdgeAccessor& edge) : type_(Type::Edge) {
new (&edge_v) EdgeAccessor(edge);
}
TypedValue(const Path& path) : type_(Type::Path) { new (&path_v) Path(path); }
TypedValue(const PropertyValue& value);
// assignment ops
@ -82,7 +110,12 @@ class TypedValue : public TotalOrdering<TypedValue, TypedValue, TypedValue> {
// because of data locality.
std::string string_v;
std::vector<TypedValue> list_v;
// Node, Edge, Path, Map missing.
// clang doesn't allow unordered_map to have incomplete type as value so we
// we use map.
std::map<std::string, TypedValue> map_v;
VertexAccessor vertex_v;
EdgeAccessor edge_v;
Path path_v;
};
/**