From a5a15673dee7ef1ba98f2af14785e41ffec367f9 Mon Sep 17 00:00:00 2001 From: Mislav Bradac Date: Mon, 13 Mar 2017 15:55:48 +0100 Subject: [PATCH] TypedValue getters return references Reviewers: buda Reviewed By: buda Subscribers: pullbot Differential Revision: https://phabricator.memgraph.io/D113 --- src/query/backend/cpp/typed_value.cpp | 558 ++++++++++++++------------ src/query/backend/cpp/typed_value.hpp | 72 ++-- 2 files changed, 346 insertions(+), 284 deletions(-) diff --git a/src/query/backend/cpp/typed_value.cpp b/src/query/backend/cpp/typed_value.cpp index 63cc4ce9c..279ea0714 100644 --- a/src/query/backend/cpp/typed_value.cpp +++ b/src/query/backend/cpp/typed_value.cpp @@ -1,58 +1,58 @@ #include "query/backend/cpp/typed_value.hpp" -#include #include +#include #include #include #include "utils/assert.hpp" -TypedValue::TypedValue(const PropertyValue& value) { +TypedValue::TypedValue(const PropertyValue &value) { switch (value.type()) { - case PropertyValue::Type::Null: - type_ = Type::Null; - return; - case PropertyValue::Type::Bool: - type_ = Type::Bool; - bool_v = value.Value(); - return; - case PropertyValue::Type::Int: - type_ = Type::Int; - int_v = value.Value(); - return; - case PropertyValue::Type::Double: - type_ = Type::Double; - double_v = value.Value(); - case PropertyValue::Type::String: - type_ = Type::String; - new (&string_v) std::string(value.Value()); - case PropertyValue::Type::List: - type_ = Type::List; - auto vec = value.Value>(); - new (&list_v) std::vector(vec.begin(), vec.end()); - return; + case PropertyValue::Type::Null: + type_ = Type::Null; + return; + case PropertyValue::Type::Bool: + type_ = Type::Bool; + bool_v = value.Value(); + return; + case PropertyValue::Type::Int: + type_ = Type::Int; + int_v = value.Value(); + return; + case PropertyValue::Type::Double: + type_ = Type::Double; + double_v = value.Value(); + case PropertyValue::Type::String: + type_ = Type::String; + new (&string_v) std::string(value.Value()); + case PropertyValue::Type::List: + type_ = Type::List; + auto vec = value.Value>(); + new (&list_v) std::vector(vec.begin(), vec.end()); + return; } permanent_fail("Unsupported type"); } TypedValue::operator PropertyValue() const { switch (type_) { - case TypedValue::Type::Null: - return PropertyValue::Null; - case TypedValue::Type::Bool: - return PropertyValue(bool_v); - case TypedValue::Type::Int: - return PropertyValue(int_v); - case TypedValue::Type::Double: - return PropertyValue(double_v); - case TypedValue::Type::String: - return PropertyValue(string_v); - case TypedValue::Type::List: - return PropertyValue( - std::vector(list_v.begin(), list_v.end())); - default: - throw TypedValueException( - "Unsupported conversion from TypedValue to PropertyValue"); + case TypedValue::Type::Null: + return PropertyValue::Null; + case TypedValue::Type::Bool: + return PropertyValue(bool_v); + case TypedValue::Type::Int: + return PropertyValue(int_v); + case TypedValue::Type::Double: + return PropertyValue(double_v); + case TypedValue::Type::String: + return PropertyValue(string_v); + case TypedValue::Type::List: + return PropertyValue( + std::vector(list_v.begin(), list_v.end())); + default: + throw TypedValueException( + "Unsupported conversion from TypedValue to PropertyValue"); } } @@ -61,32 +61,28 @@ TypedValue::operator PropertyValue() const { // Other solution would be to add additional overloads for references, for // example Value. // Value extraction template instantiations -template <> -bool TypedValue::Value() const { +template <> const bool &TypedValue::Value() const { if (type_ != TypedValue::Type::Bool) { throw TypedValueException("Incompatible template param and type"); } return bool_v; } -template <> -int64_t TypedValue::Value() const { +template <> const int64_t &TypedValue::Value() const { if (type_ != TypedValue::Type::Int) { throw TypedValueException("Incompatible template param and type"); } return int_v; } -template <> -double TypedValue::Value() const { +template <> const double &TypedValue::Value() const { if (type_ != TypedValue::Type::Double) { throw TypedValueException("Incompatible template param and type"); } return double_v; } -template <> -std::string TypedValue::Value() const { +template <> const std::string &TypedValue::Value() const { if (type_ != TypedValue::Type::String) { throw TypedValueException("Incompatible template param and type"); } @@ -94,7 +90,8 @@ std::string TypedValue::Value() const { } template <> -std::vector TypedValue::Value>() const { +const std::vector & +TypedValue::Value>() const { if (type_ != TypedValue::Type::List) { throw TypedValueException("Incompatible template param and type"); } @@ -102,7 +99,7 @@ std::vector TypedValue::Value>() const { } template <> -std::map +std::map const & TypedValue::Value>() const { if (type_ != TypedValue::Type::Map) { throw TypedValueException("Incompatible template param and type"); @@ -110,159 +107,222 @@ TypedValue::Value>() const { return map_v; } -template <> -VertexAccessor TypedValue::Value() const { +template <> const VertexAccessor &TypedValue::Value() const { if (type_ != TypedValue::Type::Vertex) { throw TypedValueException("Incompatible template param and type"); } return vertex_v; } -template <> -EdgeAccessor TypedValue::Value() const { +template <> const EdgeAccessor &TypedValue::Value() const { if (type_ != TypedValue::Type::Edge) { throw TypedValueException("Incompatible template param and type"); } return edge_v; } -template <> -Path TypedValue::Value() const { +template <> const Path &TypedValue::Value() const { if (type_ != TypedValue::Type::Path) { throw TypedValueException("Incompatible template param and type"); } return path_v; } -TypedValue::TypedValue(const TypedValue& other) : type_(other.type_) { +template <> bool &TypedValue::Value() { + if (type_ != TypedValue::Type::Bool) { + throw TypedValueException("Incompatible template param and type"); + } + return bool_v; +} + +template <> int64_t &TypedValue::Value() { + if (type_ != TypedValue::Type::Int) { + throw TypedValueException("Incompatible template param and type"); + } + return int_v; +} + +template <> double &TypedValue::Value() { + if (type_ != TypedValue::Type::Double) { + throw TypedValueException("Incompatible template param and type"); + } + return double_v; +} + +template <> std::string &TypedValue::Value() { + if (type_ != TypedValue::Type::String) { + throw TypedValueException("Incompatible template param and type"); + } + return string_v; +} + +template <> +std::vector &TypedValue::Value>() { + if (type_ != TypedValue::Type::List) { + throw TypedValueException("Incompatible template param and type"); + } + return list_v; +} + +template <> +std::map & +TypedValue::Value>() { + if (type_ != TypedValue::Type::Map) { + throw TypedValueException("Incompatible template param and type"); + } + return map_v; +} + +template <> VertexAccessor &TypedValue::Value() { + if (type_ != TypedValue::Type::Vertex) { + throw TypedValueException("Incompatible template param and type"); + } + return vertex_v; +} + +template <> EdgeAccessor &TypedValue::Value() { + if (type_ != TypedValue::Type::Edge) { + throw TypedValueException("Incompatible template param and type"); + } + return edge_v; +} + +template <> Path &TypedValue::Value() { + if (type_ != TypedValue::Type::Path) { + throw TypedValueException("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 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(other.list_v); - return; - case Type::Map: - new (&map_v) std::map(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); + case TypedValue::Type::Null: + return; + case TypedValue::Type::Bool: + this->bool_v = other.bool_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(other.list_v); + return; + case Type::Map: + new (&map_v) std::map(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"); } -std::ostream& operator<<(std::ostream& os, const TypedValue::Type type) { +std::ostream &operator<<(std::ostream &os, const TypedValue::Type type) { switch (type) { - case TypedValue::Type::Null: - return os << "null"; - case TypedValue::Type::Bool: - return os << "bool"; - 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"; + case TypedValue::Type::Null: + return os << "null"; + case TypedValue::Type::Bool: + return os << "bool"; + 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"); } -std::ostream& operator<<(std::ostream& os, const TypedValue& value) { +std::ostream &operator<<(std::ostream &os, const TypedValue &value) { switch (value.type_) { - case TypedValue::Type::Null: - return os << "Null"; - case TypedValue::Type::Bool: - return os << (value.Value() ? "true" : "false"); - case TypedValue::Type::Int: - return os << value.Value(); - case TypedValue::Type::Double: - return os << value.Value(); - case TypedValue::Type::String: - return os << value.Value(); - case TypedValue::Type::List: - os << "["; - for (const auto& x : value.Value>()) { - os << x << ","; - } - return os << "]"; - case TypedValue::Type::Map: - os << "{"; - for (const auto& x : value.Value>()) { - os << x.first << ": " << x.second << ","; - } - return os << "}"; - case TypedValue::Type::Vertex: - return os << value.Value(); - case TypedValue::Type::Edge: - return os << value.Value(); - case TypedValue::Type::Path: - return os << value.Value(); + case TypedValue::Type::Null: + return os << "Null"; + case TypedValue::Type::Bool: + return os << (value.Value() ? "true" : "false"); + case TypedValue::Type::Int: + return os << value.Value(); + case TypedValue::Type::Double: + return os << value.Value(); + case TypedValue::Type::String: + return os << value.Value(); + case TypedValue::Type::List: + os << "["; + for (const auto &x : value.Value>()) { + os << x << ","; + } + return os << "]"; + case TypedValue::Type::Map: + os << "{"; + for (const auto &x : value.Value>()) { + os << x.first << ": " << x.second << ","; + } + return os << "}"; + case TypedValue::Type::Vertex: + return os << value.Value(); + case TypedValue::Type::Edge: + return os << value.Value(); + case TypedValue::Type::Path: + return os << value.Value(); } permanent_fail("Unsupported PropertyValue::Type"); } -TypedValue& TypedValue::operator=(const TypedValue& other) { +TypedValue &TypedValue::operator=(const TypedValue &other) { // set the type of this this->~TypedValue(); type_ = other.type_; if (this != &other) { switch (other.type_) { - case TypedValue::Type::Null: - case TypedValue::Type::Bool: - this->bool_v = other.bool_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(other.list_v); - return *this; - case TypedValue::Type::Map: - new (&map_v) std::map(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; + case TypedValue::Type::Null: + case TypedValue::Type::Bool: + this->bool_v = other.bool_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(other.list_v); + return *this; + case TypedValue::Type::Map: + new (&map_v) std::map(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"); @@ -272,38 +332,38 @@ const TypedValue TypedValue::Null = TypedValue(); TypedValue::~TypedValue() { switch (type_) { - // destructor for primitive types does nothing - case Type::Null: - case Type::Bool: - case Type::Int: - case Type::Double: - return; + // destructor for primitive types does nothing + case Type::Null: + case Type::Bool: + case Type::Int: + case Type::Double: + return; - // we need to call destructors for non primitive types since we used - // placement new - case Type::String: - // Clang fails to compile ~std::string. It seems it is a bug in some - // versions of clang. using namespace std statement solves the issue. - using namespace std; - string_v.~string(); - return; - case Type::List: - using namespace std; - list_v.~vector(); - return; - case Type::Map: - using namespace std; - map_v.~map(); - return; - case Type::Vertex: - vertex_v.~VertexAccessor(); - return; - case Type::Edge: - edge_v.~EdgeAccessor(); - return; - case Type::Path: - path_v.~Path(); - return; + // we need to call destructors for non primitive types since we used + // placement new + case Type::String: + // Clang fails to compile ~std::string. It seems it is a bug in some + // versions of clang. using namespace std statement solves the issue. + using namespace std; + string_v.~string(); + return; + case Type::List: + using namespace std; + list_v.~vector(); + return; + case Type::Map: + using namespace std; + map_v.~map(); + 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"); } @@ -315,19 +375,19 @@ TypedValue::~TypedValue() { * @param value * @return */ -double ToDouble(const TypedValue& value) { +double ToDouble(const TypedValue &value) { switch (value.type()) { - case TypedValue::Type::Int: - return (double)value.Value(); - case TypedValue::Type::Double: - return value.Value(); - default: - throw TypedValueException( - "Unsupported TypedValue::Type conversion to double"); + case TypedValue::Type::Int: + return (double)value.Value(); + case TypedValue::Type::Double: + return value.Value(); + default: + throw TypedValueException( + "Unsupported TypedValue::Type conversion to double"); } } -TypedValue operator<(const TypedValue& a, const TypedValue& b) { +TypedValue operator<(const TypedValue &a, const TypedValue &b) { if (a.type() == TypedValue::Type::Bool || b.type() == TypedValue::Type::Bool) throw TypedValueException("Invalid 'less' operand types({} + {})", a.type(), b.type()); @@ -356,7 +416,7 @@ TypedValue operator<(const TypedValue& a, const TypedValue& b) { // TODO: 2 = "2" -> false, I don't think this is handled correctly at the // moment. -TypedValue operator==(const TypedValue& a, const TypedValue& b) { +TypedValue operator==(const TypedValue &a, const TypedValue &b) { if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) return TypedValue::Null; @@ -370,7 +430,8 @@ TypedValue operator==(const TypedValue& a, const TypedValue& b) { // can compare list_v-s directly. auto list1 = a.Value>(); auto list2 = b.Value>(); - if (list1.size() != list2.size()) return false; + if (list1.size() != list2.size()) + return false; for (int i = 0; i < (int)list1.size(); ++i) { if (!(list1[i] == list2[i]).Value()) { return false; @@ -417,15 +478,15 @@ TypedValue operator==(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator!(const TypedValue& a) { +TypedValue operator!(const TypedValue &a) { switch (a.type()) { - case TypedValue::Type::Null: - return TypedValue::Null; - case TypedValue::Type::Bool: - return TypedValue(!a.Value()); - default: - throw TypedValueException("Invalid logical not operand type (!{})", - a.type()); + case TypedValue::Type::Null: + return TypedValue::Null; + case TypedValue::Type::Bool: + return TypedValue(!a.Value()); + default: + throw TypedValueException("Invalid logical not operand type (!{})", + a.type()); } } @@ -435,32 +496,32 @@ TypedValue operator!(const TypedValue& a) { * @param value a value. * @return A string. */ -std::string ValueToString(const TypedValue& value) { +std::string ValueToString(const TypedValue &value) { switch (value.type()) { - case TypedValue::Type::String: - return value.Value(); - case TypedValue::Type::Int: - return std::to_string(value.Value()); - case TypedValue::Type::Double: - return fmt::format("{}", value.Value()); - // unsupported situations - default: - throw TypedValueException( - "Unsupported TypedValue::Type conversion to string"); + case TypedValue::Type::String: + return value.Value(); + case TypedValue::Type::Int: + return std::to_string(value.Value()); + case TypedValue::Type::Double: + return fmt::format("{}", value.Value()); + // unsupported situations + default: + throw TypedValueException( + "Unsupported TypedValue::Type conversion to string"); } } -TypedValue operator-(const TypedValue& a) { +TypedValue operator-(const TypedValue &a) { switch (a.type()) { - case TypedValue::Type::Null: - return TypedValue::Null; - case TypedValue::Type::Int: - return -a.Value(); - case TypedValue::Type::Double: - return -a.Value(); - default: - throw TypedValueException("Invalid unary minus operand type (-{})", - a.type()); + case TypedValue::Type::Null: + return TypedValue::Null; + case TypedValue::Type::Int: + return -a.Value(); + case TypedValue::Type::Double: + return -a.Value(); + default: + throw TypedValueException("Invalid unary minus operand type (-{})", + a.type()); } } @@ -475,13 +536,14 @@ TypedValue operator-(const TypedValue& a) { * @param op_name Name of the operation, used only for exception description, * if raised. */ -inline void EnsureArithmeticallyOk(const TypedValue& a, const TypedValue& b, - bool string_ok, const std::string& op_name) { +inline void EnsureArithmeticallyOk(const TypedValue &a, const TypedValue &b, + bool string_ok, const std::string &op_name) { if (a.type() == TypedValue::Type::Bool || b.type() == TypedValue::Type::Bool) throw TypedValueException("Invalid {} operand types {}, {}", op_name, a.type(), b.type()); - if (string_ok) return; + if (string_ok) + return; if (a.type() == TypedValue::Type::String || b.type() == TypedValue::Type::String) @@ -489,14 +551,14 @@ inline void EnsureArithmeticallyOk(const TypedValue& a, const TypedValue& b, a.type(), b.type()); } -TypedValue operator+(const TypedValue& a, const TypedValue& b) { +TypedValue operator+(const TypedValue &a, const TypedValue &b) { if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) return TypedValue::Null; if (a.type() == TypedValue::Type::List || b.type() == TypedValue::Type::List) { std::vector list; - auto append_list = [&list](const TypedValue& v) { + auto append_list = [&list](const TypedValue &v) { if (v.type() == TypedValue::Type::List) { auto list2 = v.Value>(); list.insert(list.end(), list2.begin(), list2.end()); @@ -525,7 +587,7 @@ TypedValue operator+(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator-(const TypedValue& a, const TypedValue& b) { +TypedValue operator-(const TypedValue &a, const TypedValue &b) { EnsureArithmeticallyOk(a, b, false, "subtraction"); if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) @@ -540,7 +602,7 @@ TypedValue operator-(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator/(const TypedValue& a, const TypedValue& b) { +TypedValue operator/(const TypedValue &a, const TypedValue &b) { EnsureArithmeticallyOk(a, b, false, "division"); if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) @@ -555,7 +617,7 @@ TypedValue operator/(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator*(const TypedValue& a, const TypedValue& b) { +TypedValue operator*(const TypedValue &a, const TypedValue &b) { EnsureArithmeticallyOk(a, b, false, "multiplication"); if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) @@ -570,7 +632,7 @@ TypedValue operator*(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator%(const TypedValue& a, const TypedValue& b) { +TypedValue operator%(const TypedValue &a, const TypedValue &b) { EnsureArithmeticallyOk(a, b, false, "modulo"); if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) @@ -585,13 +647,13 @@ TypedValue operator%(const TypedValue& a, const TypedValue& b) { } } -inline bool IsLogicallyOk(const TypedValue& a) { +inline bool IsLogicallyOk(const TypedValue &a) { return a.type() == TypedValue::Type::Bool || a.type() == TypedValue::Type::Null; } // TODO: Fix bugs in && and ||. null or true -> true; false and null -> false -TypedValue operator&&(const TypedValue& a, const TypedValue& b) { +TypedValue operator&&(const TypedValue &a, const TypedValue &b) { if (IsLogicallyOk(a) && IsLogicallyOk(b)) { if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) { @@ -605,7 +667,7 @@ TypedValue operator&&(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator||(const TypedValue& a, const TypedValue& b) { +TypedValue operator||(const TypedValue &a, const TypedValue &b) { if (IsLogicallyOk(a) && IsLogicallyOk(b)) { if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) { @@ -619,7 +681,7 @@ TypedValue operator||(const TypedValue& a, const TypedValue& b) { } } -TypedValue operator^(const TypedValue& a, const TypedValue& b) { +TypedValue operator^(const TypedValue &a, const TypedValue &b) { if (IsLogicallyOk(a) && IsLogicallyOk(b)) { if (a.type() == TypedValue::Type::Null || b.type() == TypedValue::Type::Null) { diff --git a/src/query/backend/cpp/typed_value.hpp b/src/query/backend/cpp/typed_value.hpp index 24ca53f7a..331e1c3f0 100644 --- a/src/query/backend/cpp/typed_value.hpp +++ b/src/query/backend/cpp/typed_value.hpp @@ -1,19 +1,19 @@ #pragma once +#include #include +#include #include #include #include -#include -#include +#include "storage/edge_accessor.hpp" +#include "storage/property_value.hpp" +#include "storage/vertex_accessor.hpp" +#include "traversal/path.hpp" #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 Path; @@ -26,11 +26,11 @@ typedef traversal_template::Path Path; * TypedValue::Type. Each such type corresponds to exactly one C++ type. */ class TypedValue : public TotalOrdering { - public: +public: /** Private default constructor, makes Null */ TypedValue() : type_(Type::Null) {} - public: +public: /** A value type. Each type corresponds to exactly one C++ type */ enum class Type : unsigned { Null, @@ -58,32 +58,32 @@ class TypedValue : public TotalOrdering { operator PropertyValue() const; /// constructors for non-primitive types - TypedValue(const std::string& value) : type_(Type::String) { + TypedValue(const std::string &value) : type_(Type::String) { new (&string_v) std::string(value); } - TypedValue(const char* value) : type_(Type::String) { + TypedValue(const char *value) : type_(Type::String) { new (&string_v) std::string(value); } - TypedValue(const std::vector& value) : type_(Type::List) { + TypedValue(const std::vector &value) : type_(Type::List) { new (&list_v) std::vector(value); } - TypedValue(const std::map& value) + TypedValue(const std::map &value) : type_(Type::Map) { new (&map_v) std::map(value); } - TypedValue(const VertexAccessor& vertex) : type_(Type::Vertex) { + TypedValue(const VertexAccessor &vertex) : type_(Type::Vertex) { new (&vertex_v) VertexAccessor(vertex); } - TypedValue(const EdgeAccessor& edge) : type_(Type::Edge) { + 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); + TypedValue(const Path &path) : type_(Type::Path) { new (&path_v) Path(path); } + TypedValue(const PropertyValue &value); // assignment ops - TypedValue& operator=(const TypedValue& other); + TypedValue &operator=(const TypedValue &other); - TypedValue(const TypedValue& other); + TypedValue(const TypedValue &other); ~TypedValue(); Type type() const { return type_; } @@ -95,12 +95,12 @@ class TypedValue : public TotalOrdering { * @tparam T Type to interpret the value as. * @return The value as type T. */ - template - T Value() const; + template T &Value(); + template const T &Value() const; - friend std::ostream& operator<<(std::ostream& stream, const TypedValue&prop); + friend std::ostream &operator<<(std::ostream &stream, const TypedValue &prop); - private: +private: // storage for the value of the property union { bool bool_v; @@ -133,31 +133,31 @@ class TypedValue : public TotalOrdering { * of incompatible Types. */ class TypedValueException : public StacktraceException { - public: +public: using ::StacktraceException::StacktraceException; }; // comparison operators // they return TypedValue because Null can be returned -TypedValue operator==(const TypedValue& a, const TypedValue& b); -TypedValue operator<(const TypedValue& a, const TypedValue& b); -TypedValue operator!(const TypedValue& a); +TypedValue operator==(const TypedValue &a, const TypedValue &b); +TypedValue operator<(const TypedValue &a, const TypedValue &b); +TypedValue operator!(const TypedValue &a); // arithmetic operators -TypedValue operator-(const TypedValue& a); -TypedValue operator+(const TypedValue& a, const TypedValue& b); -TypedValue operator-(const TypedValue& a, const TypedValue& b); -TypedValue operator/(const TypedValue& a, const TypedValue& b); -TypedValue operator*(const TypedValue& a, const TypedValue& b); -TypedValue operator%(const TypedValue& a, const TypedValue& b); +TypedValue operator-(const TypedValue &a); +TypedValue operator+(const TypedValue &a, const TypedValue &b); +TypedValue operator-(const TypedValue &a, const TypedValue &b); +TypedValue operator/(const TypedValue &a, const TypedValue &b); +TypedValue operator*(const TypedValue &a, const TypedValue &b); +TypedValue operator%(const TypedValue &a, const TypedValue &b); // binary bool operators -TypedValue operator&&(const TypedValue& a, const TypedValue& b); -TypedValue operator||(const TypedValue& a, const TypedValue& b); +TypedValue operator&&(const TypedValue &a, const TypedValue &b); +TypedValue operator||(const TypedValue &a, const TypedValue &b); // binary bool xor, not power operator // Be careful: since ^ is binary operator and || and && are logical operators // they have different priority in c++. -TypedValue operator^(const TypedValue& a, const TypedValue& b); +TypedValue operator^(const TypedValue &a, const TypedValue &b); // stream output -std::ostream& operator<<(std::ostream& os, const TypedValue::Type type); +std::ostream &operator<<(std::ostream &os, const TypedValue::Type type);