// Copyright (c) 2016-2020 Memgraph Ltd. [https://memgraph.com] // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma once #include #include #include #include #include #include #include #include #include "mgclient.h" namespace mg { namespace detail { // uint to int conversion in C++ is a bit tricky. Take a look here // https://stackoverflow.com/questions/14623266/why-cant-i-reinterpret-cast-uint-to-int // for more details. template TDest MemcpyCast(TSrc src) { TDest dest; static_assert(sizeof(dest) == sizeof(src), "MemcpyCast expects source and destination to be of same size"); static_assert(std::is_arithmetic::value, "MemcpyCast expects source is an arithmetic type"); static_assert(std::is_arithmetic::value, "MemcpyCast expects destination is an arithmetic type"); std::memcpy(&dest, &src, sizeof(src)); return dest; } } // namespace detail // Forward declarations: class ConstList; class ConstMap; class ConstNode; class ConstRelationship; class ConstUnboundRelationship; class ConstPath; class ConstDate; class ConstTime; class ConstLocalTime; class ConstDateTime; class ConstDateTimeZoneId; class ConstLocalDateTime; class ConstDuration; class ConstPoint2d; class ConstPoint3d; class ConstValue; class Value; #define CREATE_ITERATOR(container, element) \ class Iterator { \ private: \ friend class container; \ \ public: \ bool operator==(const Iterator &other) const { \ return iterable_ == other.iterable_ && index_ == other.index_; \ } \ \ bool operator!=(const Iterator &other) const { return !(*this == other); } \ \ Iterator &operator++() { \ index_++; \ return *this; \ } \ \ element operator*() const; \ \ private: \ Iterator(const container *iterable, size_t index) \ : iterable_(iterable), index_(index) {} \ \ const container *iterable_; \ size_t index_; \ } /// Wrapper for int64_t ID to prevent dangerous implicit conversions. class Id { public: Id() = default; /// Construct Id from uint64_t static Id FromUint(uint64_t id) { return Id(detail::MemcpyCast(id)); } /// Construct Id from int64_t static Id FromInt(int64_t id) { return Id(id); } int64_t AsInt() const { return id_; } uint64_t AsUint() const { return detail::MemcpyCast(id_); } bool operator==(const Id &other) const { return id_ == other.id_; } bool operator!=(const Id &other) const { return !(*this == other); } private: explicit Id(int64_t id) : id_(id) {} int64_t id_; }; //////////////////////////////////////////////////////////////////////////////// /// List: /// \brief Wrapper class for \ref mg_list. class List final { private: friend class Value; public: CREATE_ITERATOR(List, ConstValue); explicit List(mg_list *ptr) : ptr_(ptr) {} /// \brief Create a List from a copy of the given \ref mg_list. explicit List(const mg_list *const_ptr) : List(mg_list_copy(const_ptr)) {} List(const List &other); List(List &&other); List &operator=(const List &other) = delete; List &operator=(List &&other) = delete; ~List(); /// \brief Create a new list by copying the ConstList. explicit List(const ConstList &list); /// \brief Constructs a list that can hold at most \p capacity elements. /// \param capacity The maximum number of elements that the newly constructed /// list can hold. explicit List(size_t capacity) : List(mg_list_make_empty(capacity)) {} explicit List(const std::vector &values); explicit List(std::vector &&values); List(std::initializer_list list); size_t size() const { return mg_list_size(ptr_); } bool empty() const { return size() == 0; } /// \brief Returns the value at the given `index`. const ConstValue operator[](size_t index) const; Iterator begin() const { return Iterator(this, 0); } Iterator end() const { return Iterator(this, size()); } /// \brief Appends the given `value` to the list. /// The `value` is copied. bool Append(const Value &value); /// \brief Appends the given `value` to the list. /// The `value` is copied. bool Append(const ConstValue &value); /// \brief Appends the given `value` to the list. /// \note /// It takes the ownership of the `value` by moving it. /// Behaviour of accessing the `value` after performing this operation is /// considered undefined. bool Append(Value &&value); const ConstList AsConstList() const; /// \exception std::runtime_error list contains value with unknown type bool operator==(const List &other) const; /// \exception std::runtime_error list contains value with unknown type bool operator==(const ConstList &other) const; /// \exception std::runtime_error list contains value with unknown type bool operator!=(const List &other) const { return !(*this == other); } /// \exception std::runtime_error list contains value with unknown type bool operator!=(const ConstList &other) const { return !(*this == other); } const mg_list *ptr() const { return ptr_; } private: mg_list *ptr_; }; class ConstList final { public: CREATE_ITERATOR(ConstList, ConstValue); explicit ConstList(const mg_list *const_ptr) : const_ptr_(const_ptr) {} size_t size() const { return mg_list_size(const_ptr_); } bool empty() const { return size() == 0; } /// \brief Returns the value at the given `index`. const ConstValue operator[](size_t index) const; Iterator begin() const { return Iterator(this, 0); } Iterator end() const { return Iterator(this, size()); } /// \exception std::runtime_error list contains value with unknown type bool operator==(const ConstList &other) const; /// \exception std::runtime_error list contains value with unknown type bool operator==(const List &other) const; /// \exception std::runtime_error list contains value with unknown type bool operator!=(const ConstList &other) const { return !(*this == other); } /// \exception std::runtime_error list contains value with unknown type bool operator!=(const List &other) const { return !(*this == other); } const mg_list *ptr() const { return const_ptr_; } private: const mg_list *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Map: /// \brief Wrapper class for \ref mg_map. class Map final { private: friend class Value; using KeyValuePair = std::pair; public: CREATE_ITERATOR(Map, KeyValuePair); explicit Map(mg_map *ptr) : ptr_(ptr) {} /// \brief Create a Map from a copy of the given \ref mg_map. explicit Map(const mg_map *const_ptr) : Map(mg_map_copy(const_ptr)) {} Map(const Map &other); Map(Map &&other); Map &operator=(const Map &other) = delete; Map &operator=(Map &&other) = delete; ~Map(); /// Copies content of the given `map`. explicit Map(const ConstMap &map); /// \brief Constructs an empty Map that can hold at most \p capacity key-value /// pairs. /// /// Key-value pairs should be constructed and then inserted using /// \ref Insert, \ref InsertUnsafe and similar. /// /// \param capacity The maximum number of key-value pairs that the newly /// constructed Map can hold. explicit Map(size_t capacity) : Map(mg_map_make_empty(capacity)) {} /// \brief Constructs an map from the list of key-value pairs. /// Values are copied. Map(std::initializer_list> list); size_t size() const { return mg_map_size(ptr_); } bool empty() const { return size() == 0; } /// \brief Returns the value associated with the given `key`. /// Behaves undefined if there is no such a value. /// \note /// Each key-value pair has to be checked, resulting with /// O(n) time complexity. ConstValue operator[](const std::string_view key) const; Iterator begin() const { return Iterator(this, 0); } Iterator end() const { return Iterator(this, size()); } /// \brief Returns the key-value iterator for the given `key`. /// In the case there is no such pair, `end` iterator is returned. /// \note /// Each key-value pair has to be checked, resulting with O(n) time /// complexity. Iterator find(const std::string_view key) const; /// \brief Inserts the given `key`-`value` pair into the map. /// Checks if the given `key` already exists by iterating over all entries. /// Copies both the `key` and the `value`. bool Insert(const std::string_view key, const Value &value); /// \brief Inserts the given `key`-`value` pair into the map. /// Checks if the given `key` already exists by iterating over all entries. /// Copies both the `key` and the `value`. bool Insert(const std::string_view key, const ConstValue &value); /// \brief Inserts the given `key`-`value` pair into the map. /// Checks if the given `key` already exists by iterating over all entries. /// Copies the `key` and takes the ownership of `value` by moving it. /// Behaviour of accessing the `value` after performing this operation is /// considered undefined. bool Insert(const std::string_view key, Value &&value); /// \brief Inserts the given `key`-`value` pair into the map. /// It doesn't check if the given `key` already exists in the map. /// Copies both the `key` and the `value`. bool InsertUnsafe(const std::string_view key, const Value &value); /// \brief Inserts the given `key`-`value` pair into the map. /// It doesn't check if the given `key` already exists in the map. /// Copies both the `key` and the `value`. bool InsertUnsafe(const std::string_view key, const ConstValue &value); /// \brief Inserts the given `key`-`value` pair into the map. /// It doesn't check if the given `key` already exists in the map. /// Copies the `key` and takes the ownership of `value` by moving it. /// Behaviour of accessing the `value` after performing this operation /// is considered undefined. bool InsertUnsafe(const std::string_view key, Value &&value); const ConstMap AsConstMap() const; /// \exception std::runtime_error map contains value with unknown type bool operator==(const Map &other) const; /// \exception std::runtime_error map contains value with unknown type bool operator==(const ConstMap &other) const; /// \exception std::runtime_error map contains value with unknown type bool operator!=(const Map &other) const { return !(*this == other); } /// \exception std::runtime_error map contains value with unknown type bool operator!=(const ConstMap &other) const { return !(*this == other); } const mg_map *ptr() const { return ptr_; } private: mg_map *ptr_; }; class ConstMap final { private: using KeyValuePair = std::pair; public: CREATE_ITERATOR(ConstMap, KeyValuePair); explicit ConstMap(const mg_map *const_ptr) : const_ptr_(const_ptr) {} size_t size() const { return mg_map_size(const_ptr_); } bool empty() const { return size() == 0; } /// \brief Returns the value associated with the given `key`. /// Behaves undefined if there is no such a value. /// \note /// Each key-value pair has to be checked, resulting with O(n) /// time complexity. ConstValue operator[](const std::string_view key) const; Iterator begin() const { return Iterator(this, 0); } Iterator end() const { return Iterator(this, size()); } /// \brief Returns the key-value iterator for the given `key`. /// In the case there is no such pair, end iterator is returned. /// \note /// Each key-value pair has to be checked, resulting with O(n) time /// complexity. Iterator find(const std::string_view key) const; /// \exception std::runtime_error map contains value with unknown type bool operator==(const ConstMap &other) const; /// \exception std::runtime_error map contains value with unknown type bool operator==(const Map &other) const; /// \exception std::runtime_error map contains value with unknown type bool operator!=(const ConstMap &other) const { return !(*this == other); } /// \exception std::runtime_error map contains value with unknown type bool operator!=(const Map &other) const { return !(*this == other); } const mg_map *ptr() const { return const_ptr_; } private: const mg_map *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Node: /// \brief Wrapper class for \ref mg_node class Node final { private: friend class Value; public: /// \brief View of the node's labels class Labels final { public: CREATE_ITERATOR(Labels, std::string_view); explicit Labels(const mg_node *node) : node_(node) {} size_t size() const { return mg_node_label_count(node_); } /// \brief Return node's label at the `index` position. std::string_view operator[](size_t index) const; Iterator begin() { return Iterator(this, 0); } Iterator end() { return Iterator(this, size()); } private: const mg_node *node_; }; explicit Node(mg_node *ptr) : ptr_(ptr) {} /// \brief Create a Node from a copy of the given \ref mg_node. explicit Node(const mg_node *const_ptr) : Node(mg_node_copy(const_ptr)) {} Node(const Node &other); Node(Node &&other); Node &operator=(const Node &other) = delete; Node &operator=(Node &&other) = delete; ~Node(); explicit Node(const ConstNode &node); Id id() const { return Id::FromInt(mg_node_id(ptr_)); } Labels labels() const { return Labels(ptr_); } ConstMap properties() const { return ConstMap(mg_node_properties(ptr_)); } ConstNode AsConstNode() const; /// \exception std::runtime_error node property contains value with /// unknown type bool operator==(const Node &other) const; /// \exception std::runtime_error node property contains value with /// unknown type bool operator==(const ConstNode &other) const; /// \exception std::runtime_error node property contains value with /// unknown type bool operator!=(const Node &other) const { return !(*this == other); } /// \exception std::runtime_error node property contains value with /// unknown type bool operator!=(const ConstNode &other) const { return !(*this == other); } const mg_node *ptr() const { return ptr_; } private: mg_node *ptr_; }; class ConstNode final { public: explicit ConstNode(const mg_node *const_ptr) : const_ptr_(const_ptr) {} Id id() const { return Id::FromInt(mg_node_id(const_ptr_)); } Node::Labels labels() const { return Node::Labels(const_ptr_); } ConstMap properties() const { return ConstMap(mg_node_properties(const_ptr_)); } /// \exception std::runtime_error node property contains value with /// unknown type bool operator==(const ConstNode &other) const; /// \exception std::runtime_error node property contains value with /// unknown type bool operator==(const Node &other) const; /// \exception std::runtime_error node property contains value with /// unknown type bool operator!=(const ConstNode &other) const { return !(*this == other); } /// \exception std::runtime_error node property contains value with /// unknown type bool operator!=(const Node &other) const { return !(*this == other); } const mg_node *ptr() const { return const_ptr_; } private: const mg_node *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Relationship: /// \brief Wrapper class for \ref mg_relationship. class Relationship final { private: friend class Value; public: explicit Relationship(mg_relationship *ptr) : ptr_(ptr) {} /// \brief Create a Relationship from a copy the given \ref mg_relationship. explicit Relationship(const mg_relationship *const_ptr) : Relationship(mg_relationship_copy(const_ptr)) {} Relationship(const Relationship &other); Relationship(Relationship &&other); Relationship &operator=(const Relationship &other) = delete; Relationship &operator=(Relationship &&other) = delete; ~Relationship(); explicit Relationship(const ConstRelationship &rel); Id id() const { return Id::FromInt(mg_relationship_id(ptr_)); } /// \brief Return the Id of the node that is at the start of the relationship. Id from() const { return Id::FromInt(mg_relationship_start_id(ptr_)); } /// \brief Return the Id of the node that is at the end of the relationship. Id to() const { return Id::FromInt(mg_relationship_end_id(ptr_)); } std::string_view type() const; ConstMap properties() const { return ConstMap(mg_relationship_properties(ptr_)); } ConstRelationship AsConstRelationship() const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const Relationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const ConstRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const Relationship &other) const { return !(*this == other); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const ConstRelationship &other) const { return !(*this == other); } const mg_relationship *ptr() const { return ptr_; } private: mg_relationship *ptr_; }; class ConstRelationship final { public: explicit ConstRelationship(const mg_relationship *const_ptr) : const_ptr_(const_ptr) {} Id id() const { return Id::FromInt(mg_relationship_id(const_ptr_)); } /// \brief Return the Id of the node that is at the start of the relationship. Id from() const { return Id::FromInt(mg_relationship_start_id(const_ptr_)); } /// \brief Return the Id of the node that is at the end of the relationship. Id to() const { return Id::FromInt(mg_relationship_end_id(const_ptr_)); } std::string_view type() const; ConstMap properties() const { return ConstMap(mg_relationship_properties(const_ptr_)); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const ConstRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const Relationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const ConstRelationship &other) const { return !(*this == other); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const Relationship &other) const { return !(*this == other); } const mg_relationship *ptr() const { return const_ptr_; } private: const mg_relationship *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // UnboundRelationship: /// \brief Wrapper class for \ref mg_unbound_relationship. class UnboundRelationship final { private: friend class Value; public: explicit UnboundRelationship(mg_unbound_relationship *ptr) : ptr_(ptr) {} /// \brief Create an UnboundRelationship from a copy of the given /// \ref mg_unbound_relationship. explicit UnboundRelationship(const mg_unbound_relationship *const_ptr) : UnboundRelationship(mg_unbound_relationship_copy(const_ptr)) {} UnboundRelationship(const UnboundRelationship &other); UnboundRelationship(UnboundRelationship &&other); UnboundRelationship &operator=(const UnboundRelationship &other) = delete; UnboundRelationship &operator=(UnboundRelationship &&other) = delete; ~UnboundRelationship(); explicit UnboundRelationship(const ConstUnboundRelationship &rel); Id id() const { return Id::FromInt(mg_unbound_relationship_id(ptr_)); } std::string_view type() const; ConstMap properties() const { return ConstMap(mg_unbound_relationship_properties(ptr_)); } ConstUnboundRelationship AsConstUnboundRelationship() const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const UnboundRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const ConstUnboundRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const UnboundRelationship &other) const { return !(*this == other); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const ConstUnboundRelationship &other) const { return !(*this == other); } const mg_unbound_relationship *ptr() const { return ptr_; } private: mg_unbound_relationship *ptr_; }; class ConstUnboundRelationship final { public: explicit ConstUnboundRelationship(const mg_unbound_relationship *const_ptr) : const_ptr_(const_ptr) {} Id id() const { return Id::FromInt(mg_unbound_relationship_id(const_ptr_)); } std::string_view type() const; ConstMap properties() const { return ConstMap(mg_unbound_relationship_properties(const_ptr_)); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const ConstUnboundRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator==(const UnboundRelationship &other) const; /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const ConstUnboundRelationship &other) const { return !(*this == other); } /// \exception std::runtime_error relationship property contains value with /// unknown type bool operator!=(const UnboundRelationship &other) const { return !(*this == other); } const mg_unbound_relationship *ptr() const { return const_ptr_; } private: const mg_unbound_relationship *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Path: /// \brief Wrapper class for \ref mg_path. class Path final { private: friend class Value; public: explicit Path(mg_path *ptr) : ptr_(ptr) {} /// \brief Create a Path from a copy of the given \ref mg_path. explicit Path(const mg_path *const_ptr) : Path(mg_path_copy(const_ptr)) {} Path(const Path &other); Path(Path &&other); Path &operator=(const Path &other); Path &operator=(Path &&other); ~Path(); explicit Path(const ConstPath &path); /// Length of the path is number of edges. size_t length() const { return mg_path_length(ptr_); } /// \brief Returns the vertex at the given `index`. /// \pre `index` should be less than or equal to length of the path. ConstNode GetNodeAt(size_t index) const; /// \brief Returns the edge at the given `index`. /// \pre `index` should be less than length of the path. ConstUnboundRelationship GetRelationshipAt(size_t index) const; /// \brief Returns the orientation of the edge at the given `index`. /// \pre `index` should be less than length of the path. /// \return True if the edge is reversed, false otherwise. bool IsReversedRelationshipAt(size_t index) const; ConstPath AsConstPath() const; /// \exception std::runtime_error path contains elements with unknown value bool operator==(const Path &other) const; /// \exception std::runtime_error path contains elements with unknown value bool operator==(const ConstPath &other) const; /// \exception std::runtime_error path contains elements with unknown value bool operator!=(const Path &other) const { return !(*this == other); } /// \exception std::runtime_error path contains elements with unknown value bool operator!=(const ConstPath &other) const { return !(*this == other); } const mg_path *ptr() const { return ptr_; } private: mg_path *ptr_; }; class ConstPath final { public: explicit ConstPath(const mg_path *const_ptr) : const_ptr_(const_ptr) {} /// Length of the path in number of edges. size_t length() const { return mg_path_length(const_ptr_); } /// \brief Returns the vertex at the given `index`. /// \pre `index` should be less than or equal to length of the path. ConstNode GetNodeAt(size_t index) const; /// \brief Returns the edge at the given `index`. /// \pre `index` should be less than length of the path. ConstUnboundRelationship GetRelationshipAt(size_t index) const; /// \brief Returns the orientation of the edge at the given `index`. /// \pre `index` should be less than length of the path. /// \return True if the edge is reversed, false otherwise. bool IsReversedRelationshipAt(size_t index) const; /// \exception std::runtime_error path contains elements with unknown value bool operator==(const ConstPath &other) const; /// \exception std::runtime_error path contains elements with unknown value bool operator==(const Path &other) const; /// \exception std::runtime_error path contains elements with unknown value bool operator!=(const ConstPath &other) const { return !(*this == other); } /// \exception std::runtime_error path contains elements with unknown value bool operator!=(const Path &other) const { return !(*this == other); } const mg_path *ptr() const { return const_ptr_; } private: const mg_path *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Date: /// \brief Wrapper class for \ref mg_date class Date final { private: friend class Value; public: explicit Date(mg_date *ptr) : ptr_(ptr) {} explicit Date(const mg_date *const_ptr) : Date(mg_date_copy(const_ptr)) {} Date(const Date &other); Date(Date &&other); Date &operator=(const Date &other); Date &operator=(Date &&other); ~Date(); explicit Date(const ConstDate &date); /// \brief Returns days since Unix epoch. int64_t days() const { return mg_date_days(ptr_); } ConstDate AsConstDate() const; bool operator==(const Date &other) const; bool operator==(const ConstDate &other) const; bool operator!=(const Date &other) const { return !(*this == other); } bool operator!=(const ConstDate &other) const { return !(*this == other); } const mg_date *ptr() const { return ptr_; } private: mg_date *ptr_; }; class ConstDate final { public: explicit ConstDate(const mg_date *const_ptr) : const_ptr_(const_ptr) {} /// \brief Returns days since Unix epoch. int64_t days() const { return mg_date_days(const_ptr_); } bool operator==(const ConstDate &other) const; bool operator==(const Date &other) const; bool operator!=(const ConstDate &other) const { return !(*this == other); } bool operator!=(const Date &other) const { return !(*this == other); } const mg_date *ptr() const { return const_ptr_; }; private: const mg_date *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Time: /// \brief Wrapper class for \ref mg_time class Time final { private: friend class Value; public: explicit Time(mg_time *ptr) : ptr_(ptr) {} explicit Time(const mg_time *const_ptr) : Time(mg_time_copy(const_ptr)) {} Time(const Time &other); Time(Time &&other); Time &operator=(const Time &other); Time &operator=(Time &&other); ~Time(); explicit Time(const ConstTime &time); /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_time_nanoseconds(ptr_); } /// Returns time zone offset in seconds from UTC. int64_t tz_offset_seconds() const { return mg_time_tz_offset_seconds(ptr_); } ConstTime AsConstTime() const; bool operator==(const Time &other) const; bool operator==(const ConstTime &other) const; bool operator!=(const Time &other) const { return !(*this == other); } bool operator!=(const ConstTime &other) const { return !(*this == other); } const mg_time *ptr() const { return ptr_; } private: mg_time *ptr_; }; class ConstTime final { public: explicit ConstTime(const mg_time *const_ptr) : const_ptr_(const_ptr) {} /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_time_nanoseconds(const_ptr_); } /// Returns time zone offset in seconds from UTC. int64_t tz_offset_seconds() const { return mg_time_tz_offset_seconds(const_ptr_); } bool operator==(const ConstTime &other) const; bool operator==(const Time &other) const; bool operator!=(const ConstTime &other) const { return !(*this == other); } bool operator!=(const Time &other) const { return !(*this == other); } const mg_time *ptr() const { return const_ptr_; }; private: const mg_time *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // LocalTime: /// \brief Wrapper class for \ref mg_local_time class LocalTime final { private: friend class Value; public: explicit LocalTime(mg_local_time *ptr) : ptr_(ptr) {} explicit LocalTime(const mg_local_time *const_ptr) : LocalTime(mg_local_time_copy(const_ptr)) {} LocalTime(const LocalTime &other); LocalTime(LocalTime &&other); LocalTime &operator=(const LocalTime &other); LocalTime &operator=(LocalTime &&other); ~LocalTime(); explicit LocalTime(const ConstLocalTime &local_time); /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_local_time_nanoseconds(ptr_); } ConstLocalTime AsConstLocalTime() const; bool operator==(const LocalTime &other) const; bool operator==(const ConstLocalTime &other) const; bool operator!=(const LocalTime &other) const { return !(*this == other); } bool operator!=(const ConstLocalTime &other) const { return !(*this == other); } const mg_local_time *ptr() const { return ptr_; } private: mg_local_time *ptr_; }; class ConstLocalTime final { public: explicit ConstLocalTime(const mg_local_time *const_ptr) : const_ptr_(const_ptr) {} /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_local_time_nanoseconds(const_ptr_); } bool operator==(const ConstLocalTime &other) const; bool operator==(const LocalTime &other) const; bool operator!=(const ConstLocalTime &other) const { return !(*this == other); } bool operator!=(const LocalTime &other) const { return !(*this == other); } const mg_local_time *ptr() const { return const_ptr_; }; private: const mg_local_time *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // DateTime: /// \brief Wrapper class for \ref mg_date_time class DateTime final { private: friend class Value; public: explicit DateTime(mg_date_time *ptr) : ptr_(ptr) {} explicit DateTime(const mg_date_time *const_ptr) : DateTime(mg_date_time_copy(const_ptr)) {} DateTime(const DateTime &other); DateTime(DateTime &&other); DateTime &operator=(const DateTime &other); DateTime &operator=(DateTime &&other); ~DateTime(); explicit DateTime(const ConstDateTime &date_time); /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_date_time_seconds(ptr_); } /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_date_time_nanoseconds(ptr_); } /// Returns time zone offset in minutes from UTC. int64_t tz_offset_minutes() const { return mg_date_time_tz_offset_minutes(ptr_); } ConstDateTime AsConstDateTime() const; bool operator==(const DateTime &other) const; bool operator==(const ConstDateTime &other) const; bool operator!=(const DateTime &other) const { return !(*this == other); } bool operator!=(const ConstDateTime &other) const { return !(*this == other); } const mg_date_time *ptr() const { return ptr_; } private: mg_date_time *ptr_; }; class ConstDateTime final { public: explicit ConstDateTime(const mg_date_time *const_ptr) : const_ptr_(const_ptr) {} /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_date_time_seconds(const_ptr_); } /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_date_time_nanoseconds(const_ptr_); } /// Returns time zone offset in minutes from UTC. int64_t tz_offset_minutes() const { return mg_date_time_tz_offset_minutes(const_ptr_); } bool operator==(const ConstDateTime &other) const; bool operator==(const DateTime &other) const; bool operator!=(const ConstDateTime &other) const { return !(*this == other); } bool operator!=(const DateTime &other) const { return !(*this == other); } const mg_date_time *ptr() const { return const_ptr_; }; private: const mg_date_time *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // DateTimeZoneId: /// \brief Wrapper class for \ref mg_date_time_zone_id class DateTimeZoneId final { private: friend class Value; public: explicit DateTimeZoneId(mg_date_time_zone_id *ptr) : ptr_(ptr) {} explicit DateTimeZoneId(const mg_date_time_zone_id *const_ptr) : DateTimeZoneId(mg_date_time_zone_id_copy(const_ptr)) {} DateTimeZoneId(const DateTimeZoneId &other); DateTimeZoneId(DateTimeZoneId &&other); DateTimeZoneId &operator=(const DateTimeZoneId &other); DateTimeZoneId &operator=(DateTimeZoneId &&other); ~DateTimeZoneId(); explicit DateTimeZoneId(const ConstDateTimeZoneId &date_time_zone_id); /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_date_time_zone_id_seconds(ptr_); }; /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_date_time_zone_id_nanoseconds(ptr_); } /// Returns time zone represented by the identifier. int64_t tzId() const { return mg_date_time_zone_id_tz_id(ptr_); } ConstDateTimeZoneId AsConstDateTimeZoneId() const; bool operator==(const DateTimeZoneId &other) const; bool operator==(const ConstDateTimeZoneId &other) const; bool operator!=(const DateTimeZoneId &other) const { return !(*this == other); } bool operator!=(const ConstDateTimeZoneId &other) const { return !(*this == other); } const mg_date_time_zone_id *ptr() const { return ptr_; } private: mg_date_time_zone_id *ptr_; }; class ConstDateTimeZoneId final { public: explicit ConstDateTimeZoneId(const mg_date_time_zone_id *const_ptr) : const_ptr_(const_ptr) {} /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_date_time_zone_id_seconds(const_ptr_); }; /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_date_time_zone_id_nanoseconds(const_ptr_); } /// Returns time zone represented by the identifier. int64_t tzId() const { return mg_date_time_zone_id_tz_id(const_ptr_); } bool operator==(const ConstDateTimeZoneId &other) const; bool operator==(const DateTimeZoneId &other) const; bool operator!=(const ConstDateTimeZoneId &other) const { return !(*this == other); } bool operator!=(const DateTimeZoneId &other) const { return !(*this == other); } const mg_date_time_zone_id *ptr() const { return const_ptr_; }; private: const mg_date_time_zone_id *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // LocalDateTime: /// \brief Wrapper class for \ref mg_local_date_time class LocalDateTime final { private: friend class Value; public: explicit LocalDateTime(mg_local_date_time *ptr) : ptr_(ptr) {} explicit LocalDateTime(const mg_local_date_time *const_ptr) : LocalDateTime(mg_local_date_time_copy(const_ptr)) {} LocalDateTime(const LocalDateTime &other); LocalDateTime(LocalDateTime &&other); LocalDateTime &operator=(const LocalDateTime &other); LocalDateTime &operator=(LocalDateTime &&other); ~LocalDateTime(); explicit LocalDateTime(const ConstLocalDateTime &local_date_time); /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_local_date_time_seconds(ptr_); } /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_local_date_time_nanoseconds(ptr_); } ConstLocalDateTime AsConstLocalDateTime() const; bool operator==(const LocalDateTime &other) const; bool operator==(const ConstLocalDateTime &other) const; bool operator!=(const LocalDateTime &other) const { return !(*this == other); } bool operator!=(const ConstLocalDateTime &other) const { return !(*this == other); } const mg_local_date_time *ptr() const { return ptr_; } private: mg_local_date_time *ptr_; }; class ConstLocalDateTime final { public: explicit ConstLocalDateTime(const mg_local_date_time *const_ptr) : const_ptr_(const_ptr) {} /// Returns seconds since Unix epoch. int64_t seconds() const { return mg_local_date_time_seconds(const_ptr_); } /// Returns nanoseconds since midnight. int64_t nanoseconds() const { return mg_local_date_time_nanoseconds(const_ptr_); } bool operator==(const ConstLocalDateTime &other) const; bool operator==(const LocalDateTime &other) const; bool operator!=(const ConstLocalDateTime &other) const { return !(*this == other); } bool operator!=(const LocalDateTime &other) const { return !(*this == other); } const mg_local_date_time *ptr() const { return const_ptr_; }; private: const mg_local_date_time *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Duration: /// \brief Wrapper class for \ref mg_duration class Duration final { private: friend class Value; public: explicit Duration(mg_duration *ptr) : ptr_(ptr) {} explicit Duration(const mg_duration *const_ptr) : Duration(mg_duration_copy(const_ptr)) {} Duration(const Duration &other); Duration(Duration &&other); Duration &operator=(const Duration &other); Duration &operator=(Duration &&other); ~Duration(); explicit Duration(const ConstDuration &duration); /// Returns the months part of the temporal amount. int64_t months() const { return mg_duration_months(ptr_); } /// Returns the days part of the temporal amount. int64_t days() const { return mg_duration_days(ptr_); } /// Returns the seconds part of the temporal amount. int64_t seconds() const { return mg_duration_seconds(ptr_); } /// Returns the nanoseconds part of the temporal amount. int64_t nanoseconds() const { return mg_duration_nanoseconds(ptr_); } ConstDuration AsConstDuration() const; bool operator==(const Duration &other) const; bool operator==(const ConstDuration &other) const; bool operator!=(const Duration &other) const { return !(*this == other); } bool operator!=(const ConstDuration &other) const { return !(*this == other); } const mg_duration *ptr() const { return ptr_; } private: mg_duration *ptr_; }; class ConstDuration final { public: explicit ConstDuration(const mg_duration *const_ptr) : const_ptr_(const_ptr) {} /// Returns the months part of the temporal amount. int64_t months() const { return mg_duration_months(const_ptr_); } /// Returns the days part of the temporal amount. int64_t days() const { return mg_duration_days(const_ptr_); } /// Returns the seconds part of the temporal amount. int64_t seconds() const { return mg_duration_seconds(const_ptr_); } /// Returns the nanoseconds part of the temporal amount. int64_t nanoseconds() const { return mg_duration_nanoseconds(const_ptr_); } bool operator==(const ConstDuration &other) const; bool operator==(const Duration &other) const; bool operator!=(const ConstDuration &other) const { return !(*this == other); } bool operator!=(const Duration &other) const { return !(*this == other); } const mg_duration *ptr() const { return const_ptr_; }; private: const mg_duration *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Point2d: /// \brief Wrapper class for \ref mg_point_2d class Point2d final { private: friend class Value; public: explicit Point2d(mg_point_2d *ptr) : ptr_(ptr) {} explicit Point2d(const mg_point_2d *const_ptr) : Point2d(mg_point_2d_copy(const_ptr)) {} Point2d(const Point2d &other); Point2d(Point2d &&other); Point2d &operator=(const Point2d &other); Point2d &operator=(Point2d &&other); ~Point2d(); explicit Point2d(const ConstPoint2d &point_2d); /// Returns SRID of the 2D point. int64_t srid() const { return mg_point_2d_srid(ptr_); } /// Returns the x coordinate of the 2D point. double x() const { return mg_point_2d_x(ptr_); } /// Returns the y coordinate of the 2D point. double y() const { return mg_point_2d_y(ptr_); } ConstPoint2d AsConstPoint2d() const; bool operator==(const Point2d &other) const; bool operator==(const ConstPoint2d &other) const; bool operator!=(const Point2d &other) const { return !(*this == other); } bool operator!=(const ConstPoint2d &other) const { return !(*this == other); } const mg_point_2d *ptr() const { return ptr_; } private: mg_point_2d *ptr_; }; class ConstPoint2d final { public: explicit ConstPoint2d(const mg_point_2d *const_ptr) : const_ptr_(const_ptr) {} /// Returns SRID of the 2D point. int64_t srid() const { return mg_point_2d_srid(const_ptr_); } /// Returns the x coordinate of the 2D point. double x() const { return mg_point_2d_x(const_ptr_); } /// Returns the y coordinate of the 2D point. double y() const { return mg_point_2d_y(const_ptr_); } bool operator==(const ConstPoint2d &other) const; bool operator==(const Point2d &other) const; bool operator!=(const ConstPoint2d &other) const { return !(*this == other); } bool operator!=(const Point2d &other) const { return !(*this == other); } const mg_point_2d *ptr() const { return const_ptr_; }; private: const mg_point_2d *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Point3d: /// \brief Wrapper class for \ref mg_point_3d class Point3d final { private: friend class Value; public: explicit Point3d(mg_point_3d *ptr) : ptr_(ptr) {} explicit Point3d(const mg_point_3d *const_ptr) : Point3d(mg_point_3d_copy(const_ptr)) {} Point3d(const Point3d &other); Point3d(Point3d &&other); Point3d &operator=(const Point3d &other); Point3d &operator=(Point3d &&other); ~Point3d(); explicit Point3d(const ConstPoint3d &point_3d); /// Returns SRID of the 3D point. int64_t srid() const { return mg_point_3d_srid(ptr_); } /// Returns the x coordinate of the 3D point. double x() const { return mg_point_3d_x(ptr_); } /// Returns the y coordinate of the 3D point. double y() const { return mg_point_3d_y(ptr_); } /// Returns the z coordinate of the 3D point. double z() const { return mg_point_3d_z(ptr_); } ConstPoint3d AsConstPoint3d() const; bool operator==(const Point3d &other) const; bool operator==(const ConstPoint3d &other) const; bool operator!=(const Point3d &other) const { return !(*this == other); } bool operator!=(const ConstPoint3d &other) const { return !(*this == other); } const mg_point_3d *ptr() const { return ptr_; } private: mg_point_3d *ptr_; }; class ConstPoint3d final { public: explicit ConstPoint3d(const mg_point_3d *const_ptr) : const_ptr_(const_ptr) {} /// Returns SRID of the 3D point. int64_t srid() const { return mg_point_3d_srid(const_ptr_); } /// Returns the x coordinate of the 3D point. double x() const { return mg_point_3d_x(const_ptr_); } /// Returns the y coordinate of the 3D point. double y() const { return mg_point_3d_y(const_ptr_); } /// Returns the z coordinate of the 3D point. double z() const { return mg_point_3d_z(const_ptr_); } bool operator==(const ConstPoint3d &other) const; bool operator==(const Point3d &other) const; bool operator!=(const ConstPoint3d &other) const { return !(*this == other); } bool operator!=(const Point3d &other) const { return !(*this == other); } const mg_point_3d *ptr() const { return const_ptr_; }; private: const mg_point_3d *const_ptr_; }; //////////////////////////////////////////////////////////////////////////////// // Value: /// Wrapper class for \ref mg_value class Value final { private: friend class List; friend class Map; public: /// \brief Types that can be stored in a `Value`. enum class Type : uint8_t { Null, Bool, Int, Double, String, List, Map, Node, Relationship, UnboundRelationship, Path, Date, Time, LocalTime, DateTime, DateTimeZoneId, LocalDateTime, Duration, Point2d, Point3d }; /// \brief Constructs an object that becomes the owner of the given `value`. /// `value` is destroyed when a `Value` object is destroyed. explicit Value(mg_value *ptr) : ptr_(ptr) {} /// \brief Creates a Value from a copy of the given \ref mg_value. explicit Value(const mg_value *const_ptr) : Value(mg_value_copy(const_ptr)) {} Value(const Value &other); Value(Value &&other); Value &operator=(const Value &other) = delete; Value &operator=(Value &&other) = delete; ~Value(); explicit Value(const ConstValue &value); /// \brief Creates Null value. Value() : Value(mg_value_make_null()) {} // Constructors for primitive types: explicit Value(bool value) : Value(mg_value_make_bool(value)) {} explicit Value(int value) : Value(mg_value_make_integer(value)) {} explicit Value(int64_t value) : Value(mg_value_make_integer(value)) {} explicit Value(double value) : Value(mg_value_make_float(value)) {} // Constructors for string: explicit Value(const std::string_view value); explicit Value(const char *value); /// \brief Constructs a list value and takes the ownership of the `list`. /// \note /// Behaviour of accessing the `list` after performing this operation is /// considered undefined. explicit Value(List &&list); /// \brief Constructs a map value and takes the ownership of the `map`. /// \note /// Behaviour of accessing the `map` after performing this operation is /// considered undefined. explicit Value(Map &&map); /// \brief Constructs a vertex value and takes the ownership of the given /// `vertex`. \note Behaviour of accessing the `vertex` after performing this /// operation is considered undefined. explicit Value(Node &&vertex); /// \brief Constructs an edge value and takes the ownership of the given /// `edge`. \note Behaviour of accessing the `edge` after performing this /// operation is considered undefined. explicit Value(Relationship &&edge); /// \brief Constructs an unbounded edge value and takes the ownership of the /// given `edge`. \note Behaviour of accessing the `edge` after performing /// this operation is considered undefined. explicit Value(UnboundRelationship &&edge); /// \brief Constructs a path value and takes the ownership of the given /// `path`. \note Behaviour of accessing the `path` after performing this /// operation is considered undefined. explicit Value(Path &&path); /// \brief Constructs a date value and takes the ownership of the given /// `date`. \note Behaviour of accessing the `date` after performing this /// operation is considered undefined. explicit Value(Date &&date); /// \brief Constructs a time value and takes the ownership of the given /// `time`. \note Behaviour of accessing the `time` after performing this /// operation is considered undefined. explicit Value(Time &&time); /// \brief Constructs a LocalTime value and takes the ownership of the given /// `localTime`. \note Behaviour of accessing the `localTime` after performing /// this operation is considered undefined. explicit Value(LocalTime &&localTime); /// \brief Constructs a DateTime value and takes the ownership of the given /// `dateTime`. \note Behaviour of accessing the `dateTime` after performing /// this operation is considered undefined. explicit Value(DateTime &&dateTime); /// \brief Constructs a DateTimeZoneId value and takes the ownership of the /// given `dateTimeZoneId`. \note Behaviour of accessing the `dateTimeZoneId` /// after performing this operation is considered undefined. explicit Value(DateTimeZoneId &&dateTimeZoneId); /// \brief Constructs a LocalDateTime value and takes the ownership of the /// given `localDateTime`. \note Behaviour of accessing the `localDateTime` /// after performing this operation is considered undefined. explicit Value(LocalDateTime &&localDateTime); /// \brief Constructs a Duration value and takes the ownership of the given /// `duration`. \note Behaviour of accessing the `duration` after performing /// this operation is considered undefined. explicit Value(Duration &&duration); /// \brief Constructs a Point2d value and takes the ownership of the given /// `point2d`. \note Behaviour of accessing the `point2d` after performing /// this operation is considered undefined. explicit Value(Point2d &&point2d); /// \brief Constructs a Point3d value and takes the ownership of the given /// `point3d`. \note Behaviour of accessing the `point3d` after performing /// this operation is considered undefined. explicit Value(Point3d &&point3d); /// \pre value type is Type::Bool bool ValueBool() const; /// \pre value type is Type::Int int64_t ValueInt() const; /// \pre value type is Type::Double double ValueDouble() const; /// \pre value type is Type::String std::string_view ValueString() const; /// \pre value type is Type::List const ConstList ValueList() const; /// \pre value type is Type::Map const ConstMap ValueMap() const; /// \pre value type is Type::Node const ConstNode ValueNode() const; /// \pre value type is Type::Relationship const ConstRelationship ValueRelationship() const; /// \pre value type is Type::UnboundRelationship const ConstUnboundRelationship ValueUnboundRelationship() const; /// \pre value type is Type::Path const ConstPath ValuePath() const; /// \pre value type is Type::Date const ConstDate ValueDate() const; /// \pre value type is Type::Time const ConstTime ValueTime() const; /// \pre value type is Type::LocalTime const ConstLocalTime ValueLocalTime() const; /// \pre value type is Type::DateTime const ConstDateTime ValueDateTime() const; /// \pre value type is Type::DateTimeZoneId const ConstDateTimeZoneId ValueDateTimeZoneId() const; /// \pre value type is Type::LocalDateTime const ConstLocalDateTime ValueLocalDateTime() const; /// \pre value type is Type::Duration const ConstDuration ValueDuration() const; /// \pre value type is Type::Point2d const ConstPoint2d ValuePoint2d() const; /// \pre value type is Type::Point3d const ConstPoint3d ValuePoint3d() const; /// \exception std::runtime_error the value type is unknown Type type() const; ConstValue AsConstValue() const; /// \exception std::runtime_error the value type is unknown bool operator==(const Value &other) const; /// \exception std::runtime_error the value type is unknown bool operator==(const ConstValue &other) const; /// \exception std::runtime_error the value type is unknown bool operator!=(const Value &other) const { return !(*this == other); } /// \exception std::runtime_error the value type is unknown bool operator!=(const ConstValue &other) const { return !(*this == other); } const mg_value *ptr() const { return ptr_; } private: mg_value *ptr_; }; class ConstValue final { public: explicit ConstValue(const mg_value *const_ptr) : const_ptr_(const_ptr) {} /// \pre value type is Type::Bool bool ValueBool() const; /// \pre value type is Type::Int int64_t ValueInt() const; /// \pre value type is Type::Double double ValueDouble() const; /// \pre value type is Type::String std::string_view ValueString() const; /// \pre value type is Type::List const ConstList ValueList() const; /// \pre value type is Type::Map const ConstMap ValueMap() const; /// \pre value type is Type::Node const ConstNode ValueNode() const; /// \pre value type is Type::Relationship const ConstRelationship ValueRelationship() const; /// \pre value type is Type::UnboundRelationship const ConstUnboundRelationship ValueUnboundRelationship() const; /// \pre value type is Type::Path const ConstPath ValuePath() const; /// \pre value type is Type::Date const ConstDate ValueDate() const; /// \pre value type is Type::Time const ConstTime ValueTime() const; /// \pre value type is Type::LocalTime const ConstLocalTime ValueLocalTime() const; /// \pre value type is Type::DateTime const ConstDateTime ValueDateTime() const; /// \pre value type is Type::DateTimeZoneId const ConstDateTimeZoneId ValueDateTimeZoneId() const; /// \pre value type is Type::LocalDateTime const ConstLocalDateTime ValueLocalDateTime() const; /// \pre value type is Type::Duration const ConstDuration ValueDuration() const; /// \pre value type is Type::Point2d const ConstPoint2d ValuePoint2d() const; /// \pre value type is Type::Point3d const ConstPoint3d ValuePoint3d() const; /// \exception std::runtime_error the value type is unknown Value::Type type() const; /// \exception std::runtime_error the value type is unknown bool operator==(const ConstValue &other) const; /// \exception std::runtime_error the value type is unknown bool operator==(const Value &other) const; /// \exception std::runtime_error the value type is unknown bool operator!=(const ConstValue &other) const { return !(*this == other); } /// \exception std::runtime_error the value type is unknown bool operator!=(const Value &other) const { return !(*this == other); } const mg_value *ptr() const { return const_ptr_; } private: const mg_value *const_ptr_; }; #undef CREATE_ITERATOR namespace detail { inline std::string_view ConvertString(const mg_string *str) { return std::string_view(mg_string_data(str), mg_string_size(str)); } inline Value::Type ConvertType(mg_value_type type) { switch (type) { case MG_VALUE_TYPE_NULL: return Value::Type::Null; case MG_VALUE_TYPE_BOOL: return Value::Type::Bool; case MG_VALUE_TYPE_INTEGER: return Value::Type::Int; case MG_VALUE_TYPE_FLOAT: return Value::Type::Double; case MG_VALUE_TYPE_STRING: return Value::Type::String; case MG_VALUE_TYPE_LIST: return Value::Type::List; case MG_VALUE_TYPE_MAP: return Value::Type::Map; case MG_VALUE_TYPE_NODE: return Value::Type::Node; case MG_VALUE_TYPE_RELATIONSHIP: return Value::Type::Relationship; case MG_VALUE_TYPE_UNBOUND_RELATIONSHIP: return Value::Type::UnboundRelationship; case MG_VALUE_TYPE_PATH: return Value::Type::Path; case MG_VALUE_TYPE_DATE: return Value::Type::Date; case MG_VALUE_TYPE_TIME: return Value::Type::Time; case MG_VALUE_TYPE_LOCAL_TIME: return Value::Type::LocalTime; case MG_VALUE_TYPE_DATE_TIME: return Value::Type::DateTime; case MG_VALUE_TYPE_DATE_TIME_ZONE_ID: return Value::Type::DateTimeZoneId; case MG_VALUE_TYPE_LOCAL_DATE_TIME: return Value::Type::LocalDateTime; case MG_VALUE_TYPE_DURATION: return Value::Type::Duration; case MG_VALUE_TYPE_POINT_2D: return Value::Type::Point2d; case MG_VALUE_TYPE_POINT_3D: return Value::Type::Point3d; case MG_VALUE_TYPE_UNKNOWN: throw std::runtime_error("Unknown value type!"); } std::abort(); } inline bool AreValuesEqual(const mg_value *value1, const mg_value *value2); inline bool AreListsEqual(const mg_list *list1, const mg_list *list2) { if (list1 == list2) { return true; } if (mg_list_size(list1) != mg_list_size(list2)) { return false; } const size_t len = mg_list_size(list1); for (size_t i = 0; i < len; ++i) { if (!detail::AreValuesEqual(mg_list_at(list1, i), mg_list_at(list2, i))) { return false; } } return true; } inline bool AreMapsEqual(const mg_map *map1, const mg_map *map2) { if (map1 == map2) { return true; } if (mg_map_size(map1) != mg_map_size(map2)) { return false; } const size_t len = mg_map_size(map1); for (size_t i = 0; i < len; ++i) { const mg_string *key = mg_map_key_at(map1, i); const mg_value *value1 = mg_map_value_at(map1, i); const mg_value *value2 = mg_map_at2(map2, mg_string_size(key), mg_string_data(key)); if (value2 == nullptr) { return false; } if (!detail::AreValuesEqual(value1, value2)) { return false; } } return true; } inline bool AreNodesEqual(const mg_node *node1, const mg_node *node2) { if (node1 == node2) { return true; } if (mg_node_id(node1) != mg_node_id(node2)) { return false; } if (mg_node_label_count(node1) != mg_node_label_count(node2)) { return false; } std::set labels1; std::set labels2; const size_t label_count = mg_node_label_count(node1); for (size_t i = 0; i < label_count; ++i) { labels1.insert(detail::ConvertString(mg_node_label_at(node1, i))); labels2.insert(detail::ConvertString(mg_node_label_at(node2, i))); } if (labels1 != labels2) { return false; } return detail::AreMapsEqual(mg_node_properties(node1), mg_node_properties(node2)); } inline bool AreRelationshipsEqual(const mg_relationship *rel1, const mg_relationship *rel2) { if (rel1 == rel2) { return true; } if (mg_relationship_id(rel1) != mg_relationship_id(rel2)) { return false; } if (mg_relationship_start_id(rel1) != mg_relationship_start_id(rel2)) { return false; } if (mg_relationship_end_id(rel1) != mg_relationship_end_id(rel2)) { return false; } if (detail::ConvertString(mg_relationship_type(rel1)) != detail::ConvertString(mg_relationship_type(rel2))) { return false; } return detail::AreMapsEqual(mg_relationship_properties(rel1), mg_relationship_properties(rel2)); } inline bool AreUnboundRelationshipsEqual(const mg_unbound_relationship *rel1, const mg_unbound_relationship *rel2) { if (rel1 == rel2) { return true; } if (mg_unbound_relationship_id(rel1) != mg_unbound_relationship_id(rel2)) { return false; } if (detail::ConvertString(mg_unbound_relationship_type(rel1)) != detail::ConvertString(mg_unbound_relationship_type(rel2))) { return false; } return detail::AreMapsEqual(mg_unbound_relationship_properties(rel1), mg_unbound_relationship_properties(rel2)); } inline bool ArePathsEqual(const mg_path *path1, const mg_path *path2) { if (path1 == path2) { return true; } if (mg_path_length(path1) != mg_path_length(path2)) { return false; } const size_t len = mg_path_length(path1); for (size_t i = 0; i < len; ++i) { if (!detail::AreNodesEqual(mg_path_node_at(path1, i), mg_path_node_at(path2, i))) { return false; } if (!detail::AreUnboundRelationshipsEqual( mg_path_relationship_at(path1, i), mg_path_relationship_at(path2, i))) { return false; } if (mg_path_relationship_reversed_at(path1, i) != mg_path_relationship_reversed_at(path2, i)) { return false; } } return detail::AreNodesEqual(mg_path_node_at(path1, len), mg_path_node_at(path2, len)); } inline bool AreDatesEqual(const mg_date *date1, const mg_date *date2) { return mg_date_days(date1) == mg_date_days(date2); } inline bool AreTimesEqual(const mg_time *time1, const mg_time *time2) { return mg_time_nanoseconds(time1) == mg_time_nanoseconds(time2) && mg_time_tz_offset_seconds(time1) == mg_time_tz_offset_seconds(time2); } inline bool AreLocalTimesEqual(const mg_local_time *local_time1, const mg_local_time *local_time2) { return mg_local_time_nanoseconds(local_time1) == mg_local_time_nanoseconds(local_time2); } inline bool AreDateTimesEqual(const mg_date_time *date_time1, const mg_date_time *date_time2) { return mg_date_time_seconds(date_time1) == mg_date_time_seconds(date_time2) && mg_date_time_nanoseconds(date_time1) == mg_date_time_nanoseconds(date_time2) && mg_date_time_tz_offset_minutes(date_time1) == mg_date_time_tz_offset_minutes(date_time2); } inline bool AreDateTimeZoneIdsEqual( const mg_date_time_zone_id *date_time_zone_id1, const mg_date_time_zone_id *date_time_zone_id2) { return mg_date_time_zone_id_seconds(date_time_zone_id1) == mg_date_time_zone_id_seconds(date_time_zone_id2) && mg_date_time_zone_id_nanoseconds(date_time_zone_id1) == mg_date_time_zone_id_nanoseconds(date_time_zone_id2) && mg_date_time_zone_id_tz_id(date_time_zone_id1) == mg_date_time_zone_id_tz_id(date_time_zone_id2); } inline bool AreLocalDateTimesEqual(const mg_local_date_time *local_date_time1, const mg_local_date_time *local_date_time2) { return mg_local_date_time_seconds(local_date_time1) == mg_local_date_time_seconds(local_date_time2) && mg_local_date_time_nanoseconds(local_date_time1) == mg_local_date_time_nanoseconds(local_date_time2); } inline bool AreDurationsEqual(const mg_duration *duration1, const mg_duration *duration2) { return mg_duration_months(duration1) == mg_duration_months(duration2) && mg_duration_days(duration1) == mg_duration_days(duration2) && mg_duration_seconds(duration1) == mg_duration_seconds(duration2) && mg_duration_nanoseconds(duration1) == mg_duration_nanoseconds(duration2); } inline bool ArePoint2dsEqual(const mg_point_2d *point_2d1, const mg_point_2d *point_2d2) { return mg_point_2d_srid(point_2d1) == mg_point_2d_srid(point_2d2) && mg_point_2d_x(point_2d1) == mg_point_2d_x(point_2d2) && mg_point_2d_y(point_2d1) == mg_point_2d_y(point_2d2); } inline bool ArePoint3dsEqual(const mg_point_3d *point_3d1, const mg_point_3d *point_3d2) { return mg_point_3d_srid(point_3d1) == mg_point_3d_srid(point_3d2) && mg_point_3d_x(point_3d1) == mg_point_3d_x(point_3d2) && mg_point_3d_y(point_3d1) == mg_point_3d_y(point_3d2) && mg_point_3d_z(point_3d1) == mg_point_3d_z(point_3d2); } inline bool AreValuesEqual(const mg_value *value1, const mg_value *value2) { if (value1 == value2) { return true; } if (mg_value_get_type(value1) != mg_value_get_type(value2)) { return false; } switch (mg_value_get_type(value1)) { case MG_VALUE_TYPE_NULL: return true; case MG_VALUE_TYPE_BOOL: return mg_value_bool(value1) == mg_value_bool(value2); case MG_VALUE_TYPE_INTEGER: return mg_value_integer(value1) == mg_value_integer(value2); case MG_VALUE_TYPE_FLOAT: return mg_value_float(value1) == mg_value_float(value2); case MG_VALUE_TYPE_STRING: return detail::ConvertString(mg_value_string(value1)) == detail::ConvertString(mg_value_string(value2)); case MG_VALUE_TYPE_LIST: return detail::AreListsEqual(mg_value_list(value1), mg_value_list(value2)); case MG_VALUE_TYPE_MAP: return detail::AreMapsEqual(mg_value_map(value1), mg_value_map(value2)); case MG_VALUE_TYPE_NODE: return detail::AreNodesEqual(mg_value_node(value1), mg_value_node(value2)); case MG_VALUE_TYPE_RELATIONSHIP: return detail::AreRelationshipsEqual(mg_value_relationship(value1), mg_value_relationship(value2)); case MG_VALUE_TYPE_UNBOUND_RELATIONSHIP: return detail::AreUnboundRelationshipsEqual( mg_value_unbound_relationship(value1), mg_value_unbound_relationship(value2)); case MG_VALUE_TYPE_PATH: return detail::ArePathsEqual(mg_value_path(value1), mg_value_path(value2)); case MG_VALUE_TYPE_DATE: return detail::AreDatesEqual(mg_value_date(value1), mg_value_date(value2)); case MG_VALUE_TYPE_TIME: return detail::AreTimesEqual(mg_value_time(value1), mg_value_time(value2)); case MG_VALUE_TYPE_LOCAL_TIME: return detail::AreLocalTimesEqual(mg_value_local_time(value1), mg_value_local_time(value2)); case MG_VALUE_TYPE_DATE_TIME: return detail::AreDateTimesEqual(mg_value_date_time(value1), mg_value_date_time(value2)); case MG_VALUE_TYPE_DATE_TIME_ZONE_ID: return detail::AreDateTimeZoneIdsEqual( mg_value_date_time_zone_id(value1), mg_value_date_time_zone_id(value2)); case MG_VALUE_TYPE_LOCAL_DATE_TIME: return detail::AreLocalDateTimesEqual(mg_value_local_date_time(value1), mg_value_local_date_time(value2)); case MG_VALUE_TYPE_DURATION: return detail::AreDurationsEqual(mg_value_duration(value1), mg_value_duration(value2)); case MG_VALUE_TYPE_POINT_2D: return detail::ArePoint2dsEqual(mg_value_point_2d(value1), mg_value_point_2d(value2)); case MG_VALUE_TYPE_POINT_3D: return detail::ArePoint3dsEqual(mg_value_point_3d(value1), mg_value_point_3d(value2)); case MG_VALUE_TYPE_UNKNOWN: throw std::runtime_error("Comparing values of unknown types!"); } std::abort(); } } // namespace detail //////////////////////////////////////////////////////////////////////////////// // List: inline ConstValue List::Iterator::operator*() const { return (*iterable_)[index_]; } inline List::List(const List &other) : ptr_(mg_list_copy(other.ptr_)) {} inline List::List(List &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline List::~List() { if (ptr_ != nullptr) { mg_list_destroy(ptr_); } } inline List::List(const ConstList &list) : ptr_(mg_list_copy(list.ptr())) {} inline List::List(const std::vector &values) : List(values.size()) { for (const auto &value : values) { Append(value); } } inline List::List(std::vector &&values) : List(values.size()) { for (auto &value : values) { Append(std::move(value)); } } inline List::List(std::initializer_list values) : List(values.size()) { for (const auto &value : values) { Append(value); } } inline const ConstValue List::operator[](size_t index) const { return ConstValue(mg_list_at(ptr_, index)); } inline bool List::Append(const Value &value) { return mg_list_append(ptr_, mg_value_copy(value.ptr())) == 0; } inline bool List::Append(const ConstValue &value) { return mg_list_append(ptr_, mg_value_copy(value.ptr())) == 0; } inline bool List::Append(Value &&value) { bool result = mg_list_append(ptr_, value.ptr_) == 0; value.ptr_ = nullptr; return result; } inline const ConstList List::AsConstList() const { return ConstList(ptr_); } inline bool List::operator==(const List &other) const { return detail::AreListsEqual(ptr_, other.ptr_); } inline bool List::operator==(const ConstList &other) const { return detail::AreListsEqual(ptr_, other.ptr()); } inline ConstValue ConstList::Iterator::operator*() const { return (*iterable_)[index_]; } inline const ConstValue ConstList::operator[](size_t index) const { return ConstValue(mg_list_at(const_ptr_, index)); } inline bool ConstList::operator==(const ConstList &other) const { return detail::AreListsEqual(const_ptr_, other.const_ptr_); } inline bool ConstList::operator==(const List &other) const { return detail::AreListsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Map: inline std::pair Map::Iterator::operator*() const { return std::make_pair( detail::ConvertString(mg_map_key_at(iterable_->ptr(), index_)), ConstValue(mg_map_value_at(iterable_->ptr(), index_))); } inline Map::Map(const Map &other) : Map(mg_map_copy(other.ptr_)) {} inline Map::Map(Map &&other) : Map(other.ptr_) { other.ptr_ = nullptr; } inline Map::Map(const ConstMap &map) : ptr_(mg_map_copy(map.ptr())) {} inline Map::~Map() { if (ptr_ != nullptr) { mg_map_destroy(ptr_); } } inline Map::Map(std::initializer_list> list) : Map(list.size()) { for (const auto &[key, value] : list) { Insert(key, value.AsConstValue()); } } inline ConstValue Map::operator[](const std::string_view key) const { return ConstValue(mg_map_at2(ptr_, key.size(), key.data())); } inline Map::Iterator Map::find(const std::string_view key) const { for (size_t i = 0; i < size(); ++i) { if (key == detail::ConvertString(mg_map_key_at(ptr_, i))) { return Iterator(this, i); } } return end(); } inline bool Map::Insert(const std::string_view key, const Value &value) { return mg_map_insert2(ptr_, mg_string_make2(key.size(), key.data()), mg_value_copy(value.ptr())) == 0; } inline bool Map::Insert(const std::string_view key, const ConstValue &value) { return mg_map_insert2(ptr_, mg_string_make2(key.size(), key.data()), mg_value_copy(value.ptr())) == 0; } inline bool Map::Insert(const std::string_view key, Value &&value) { bool result = mg_map_insert2(ptr_, mg_string_make2(key.size(), key.data()), value.ptr_) == 0; value.ptr_ = nullptr; return result; } inline bool Map::InsertUnsafe(const std::string_view key, const Value &value) { return mg_map_insert_unsafe2(ptr_, mg_string_make2(key.size(), key.data()), mg_value_copy(value.ptr())) == 0; } inline bool Map::InsertUnsafe(const std::string_view key, const ConstValue &value) { return mg_map_insert_unsafe2(ptr_, mg_string_make2(key.size(), key.data()), mg_value_copy(value.ptr())) == 0; } inline bool Map::InsertUnsafe(const std::string_view key, Value &&value) { bool result = mg_map_insert_unsafe2(ptr_, mg_string_make2(key.size(), key.data()), value.ptr_) == 0; value.ptr_ = nullptr; return result; } inline const ConstMap Map::AsConstMap() const { return ConstMap(ptr_); } inline bool Map::operator==(const Map &other) const { return detail::AreMapsEqual(ptr_, other.ptr_); } inline bool Map::operator==(const ConstMap &other) const { return detail::AreMapsEqual(ptr_, other.ptr()); } inline std::pair ConstMap::Iterator::operator*() const { return std::make_pair( detail::ConvertString(mg_map_key_at(iterable_->ptr(), index_)), ConstValue(mg_map_value_at(iterable_->ptr(), index_))); } inline ConstValue ConstMap::operator[](const std::string_view key) const { return ConstValue(mg_map_at2(const_ptr_, key.size(), key.data())); } inline ConstMap::Iterator ConstMap::find(const std::string_view key) const { for (size_t i = 0; i < size(); ++i) { if (key == detail::ConvertString(mg_map_key_at(const_ptr_, i))) { return Iterator(this, i); } } return end(); } inline bool ConstMap::operator==(const ConstMap &other) const { return detail::AreMapsEqual(const_ptr_, other.const_ptr_); } inline bool ConstMap::operator==(const Map &other) const { return detail::AreMapsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Node: inline std::string_view Node::Labels::Iterator::operator*() const { return (*iterable_)[index_]; } inline std::string_view Node::Labels::operator[](size_t index) const { return detail::ConvertString(mg_node_label_at(node_, index)); } inline Node::Node(const Node &other) : Node(mg_node_copy(other.ptr_)) {} inline Node::Node(Node &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Node::~Node() { if (ptr_ != nullptr) { mg_node_destroy(ptr_); } } inline Node::Node(const ConstNode &node) : ptr_(mg_node_copy(node.ptr())) {} inline bool Node::operator==(const Node &other) const { return detail::AreNodesEqual(ptr_, other.ptr_); } inline bool Node::operator==(const ConstNode &other) const { return detail::AreNodesEqual(ptr_, other.ptr()); } inline ConstNode Node::AsConstNode() const { return ConstNode(ptr_); } inline bool ConstNode::operator==(const ConstNode &other) const { return detail::AreNodesEqual(const_ptr_, other.const_ptr_); } inline bool ConstNode::operator==(const Node &other) const { return detail::AreNodesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Relationship: inline Relationship::Relationship(const Relationship &other) : Relationship(mg_relationship_copy(other.ptr_)) {} inline Relationship::Relationship(Relationship &&other) : Relationship(other.ptr_) { other.ptr_ = nullptr; } inline Relationship::~Relationship() { if (ptr_ != nullptr) { mg_relationship_destroy(ptr_); } } inline Relationship::Relationship(const ConstRelationship &rel) : ptr_(mg_relationship_copy(rel.ptr())) {} inline std::string_view Relationship::type() const { return detail::ConvertString(mg_relationship_type(ptr_)); } inline ConstRelationship Relationship::AsConstRelationship() const { return ConstRelationship(ptr_); } inline bool Relationship::operator==(const Relationship &other) const { return detail::AreRelationshipsEqual(ptr_, other.ptr_); } inline bool Relationship::operator==(const ConstRelationship &other) const { return detail::AreRelationshipsEqual(ptr_, other.ptr()); } inline std::string_view ConstRelationship::type() const { return detail::ConvertString(mg_relationship_type(const_ptr_)); } inline bool ConstRelationship::operator==( const ConstRelationship &other) const { return detail::AreRelationshipsEqual(const_ptr_, other.const_ptr_); } inline bool ConstRelationship::operator==(const Relationship &other) const { return detail::AreRelationshipsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // UnboundRelationship: inline UnboundRelationship::UnboundRelationship( const UnboundRelationship &other) : ptr_(mg_unbound_relationship_copy(other.ptr_)) {} inline UnboundRelationship::UnboundRelationship(UnboundRelationship &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline UnboundRelationship::~UnboundRelationship() { if (ptr_ != nullptr) { mg_unbound_relationship_destroy(ptr_); } } inline UnboundRelationship::UnboundRelationship( const ConstUnboundRelationship &rel) : ptr_(mg_unbound_relationship_copy(rel.ptr())) {} inline std::string_view UnboundRelationship::type() const { return detail::ConvertString(mg_unbound_relationship_type(ptr_)); } inline ConstUnboundRelationship UnboundRelationship::AsConstUnboundRelationship() const { return ConstUnboundRelationship(ptr_); } inline bool UnboundRelationship::operator==( const UnboundRelationship &other) const { return detail::AreUnboundRelationshipsEqual(ptr_, other.ptr_); } inline bool UnboundRelationship::operator==( const ConstUnboundRelationship &other) const { return detail::AreUnboundRelationshipsEqual(ptr_, other.ptr()); } inline std::string_view ConstUnboundRelationship::type() const { return detail::ConvertString(mg_unbound_relationship_type(const_ptr_)); } inline bool ConstUnboundRelationship::operator==( const ConstUnboundRelationship &other) const { return detail::AreUnboundRelationshipsEqual(const_ptr_, other.const_ptr_); } inline bool ConstUnboundRelationship::operator==( const UnboundRelationship &other) const { return detail::AreUnboundRelationshipsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Path: inline Path::Path(const Path &other) : ptr_(mg_path_copy(other.ptr_)) {} inline Path::Path(Path &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Path::~Path() { if (ptr_ != nullptr) { mg_path_destroy(ptr_); } } inline Path::Path(const ConstPath &path) : ptr_(mg_path_copy(path.ptr())) {} inline ConstNode Path::GetNodeAt(size_t index) const { auto vertex_ptr = mg_path_node_at(ptr_, index); if (vertex_ptr == nullptr) { std::abort(); } return ConstNode(vertex_ptr); } inline ConstUnboundRelationship Path::GetRelationshipAt(size_t index) const { auto edge_ptr = mg_path_relationship_at(ptr_, index); if (edge_ptr == nullptr) { std::abort(); } return ConstUnboundRelationship(edge_ptr); } inline bool Path::IsReversedRelationshipAt(size_t index) const { auto is_reversed = mg_path_relationship_reversed_at(ptr_, index); if (is_reversed == -1) { std::abort(); } return is_reversed == 1; } inline ConstPath Path::AsConstPath() const { return ConstPath(ptr_); } inline bool Path::operator==(const Path &other) const { return detail::ArePathsEqual(ptr_, other.ptr_); } inline bool Path::operator==(const ConstPath &other) const { return detail::ArePathsEqual(ptr_, other.ptr()); } inline ConstNode ConstPath::GetNodeAt(size_t index) const { auto vertex_ptr = mg_path_node_at(const_ptr_, index); if (vertex_ptr == nullptr) { std::abort(); } return ConstNode(vertex_ptr); } inline ConstUnboundRelationship ConstPath::GetRelationshipAt( size_t index) const { auto edge_ptr = mg_path_relationship_at(const_ptr_, index); if (edge_ptr == nullptr) { std::abort(); } return ConstUnboundRelationship(edge_ptr); } inline bool ConstPath::IsReversedRelationshipAt(size_t index) const { auto is_reversed = mg_path_relationship_reversed_at(const_ptr_, index); if (is_reversed == -1) { std::abort(); } return is_reversed == 1; } inline bool ConstPath::operator==(const ConstPath &other) const { return detail::ArePathsEqual(const_ptr_, other.const_ptr_); } inline bool ConstPath::operator==(const Path &other) const { return detail::ArePathsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Date: inline Date::Date(const Date &other) : ptr_(mg_date_copy(other.ptr_)) {} inline Date::Date(Date &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Date &Date::operator=(const Date &other) { ptr_ = mg_date_copy(other.ptr_); return *this; } inline Date &Date::operator=(Date &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline Date::~Date() { if (ptr_ != nullptr) { mg_date_destroy(ptr_); } } inline Date::Date(const ConstDate &date) : ptr_(mg_date_copy(date.ptr())) {} inline ConstDate Date::AsConstDate() const { return ConstDate(ptr_); } inline bool Date::operator==(const Date &other) const { return detail::AreDatesEqual(ptr_, other.ptr_); } inline bool Date::operator==(const ConstDate &other) const { return detail::AreDatesEqual(ptr_, other.ptr()); } inline bool ConstDate::operator==(const ConstDate &other) const { return detail::AreDatesEqual(const_ptr_, other.const_ptr_); } inline bool ConstDate::operator==(const Date &other) const { return detail::AreDatesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Time: inline Time::Time(const Time &other) : ptr_(mg_time_copy(other.ptr_)) {} inline Time::Time(Time &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Time &Time::operator=(const Time &other) { ptr_ = mg_time_copy(other.ptr_); return *this; } inline Time &Time::operator=(Time &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline Time::~Time() { if (ptr_ != nullptr) { mg_time_destroy(ptr_); } } inline Time::Time(const ConstTime &time) : ptr_(mg_time_copy(time.ptr())) {} inline ConstTime Time::AsConstTime() const { return ConstTime(ptr_); } inline bool Time::operator==(const Time &other) const { return detail::AreTimesEqual(ptr_, other.ptr_); } inline bool Time::operator==(const ConstTime &other) const { return detail::AreTimesEqual(ptr_, other.ptr()); } inline bool ConstTime::operator==(const ConstTime &other) const { return detail::AreTimesEqual(const_ptr_, other.const_ptr_); } inline bool ConstTime::operator==(const Time &other) const { return detail::AreTimesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // LocalTime: inline LocalTime::LocalTime(const LocalTime &other) : ptr_(mg_local_time_copy(other.ptr_)) {} inline LocalTime::LocalTime(LocalTime &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline LocalTime &LocalTime::operator=(const LocalTime &other) { ptr_ = mg_local_time_copy(other.ptr_); return *this; } inline LocalTime &LocalTime::operator=(LocalTime &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline LocalTime::~LocalTime() { if (ptr_ != nullptr) { mg_local_time_destroy(ptr_); } } inline LocalTime::LocalTime(const ConstLocalTime &local_time) : ptr_(mg_local_time_copy(local_time.ptr())) {} inline ConstLocalTime LocalTime::AsConstLocalTime() const { return ConstLocalTime(ptr_); } inline bool LocalTime::operator==(const LocalTime &other) const { return detail::AreLocalTimesEqual(ptr_, other.ptr_); } inline bool LocalTime::operator==(const ConstLocalTime &other) const { return detail::AreLocalTimesEqual(ptr_, other.ptr()); } inline bool ConstLocalTime::operator==(const ConstLocalTime &other) const { return detail::AreLocalTimesEqual(const_ptr_, other.const_ptr_); } inline bool ConstLocalTime::operator==(const LocalTime &other) const { return detail::AreLocalTimesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // DateTime: inline DateTime::DateTime(const DateTime &other) : ptr_(mg_date_time_copy(other.ptr_)) {} inline DateTime::DateTime(DateTime &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline DateTime &DateTime::operator=(const DateTime &other) { ptr_ = mg_date_time_copy(other.ptr_); return *this; } inline DateTime &DateTime::operator=(DateTime &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline DateTime::~DateTime() { if (ptr_ != nullptr) { mg_date_time_destroy(ptr_); } } inline DateTime::DateTime(const ConstDateTime &date_time) : ptr_(mg_date_time_copy(date_time.ptr())) {} inline ConstDateTime DateTime::AsConstDateTime() const { return ConstDateTime(ptr_); } inline bool DateTime::operator==(const DateTime &other) const { return detail::AreDateTimesEqual(ptr_, other.ptr_); } inline bool DateTime::operator==(const ConstDateTime &other) const { return detail::AreDateTimesEqual(ptr_, other.ptr()); } inline bool ConstDateTime::operator==(const ConstDateTime &other) const { return detail::AreDateTimesEqual(const_ptr_, other.const_ptr_); } inline bool ConstDateTime::operator==(const DateTime &other) const { return detail::AreDateTimesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // DateTimeZoneId: inline DateTimeZoneId::DateTimeZoneId(const DateTimeZoneId &other) : ptr_(mg_date_time_zone_id_copy(other.ptr_)) {} inline DateTimeZoneId::DateTimeZoneId(DateTimeZoneId &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline DateTimeZoneId &DateTimeZoneId::operator=(const DateTimeZoneId &other) { ptr_ = mg_date_time_zone_id_copy(other.ptr_); return *this; } inline DateTimeZoneId &DateTimeZoneId::operator=(DateTimeZoneId &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline DateTimeZoneId::~DateTimeZoneId() { if (ptr_ != nullptr) { mg_date_time_zone_id_destroy(ptr_); } } inline DateTimeZoneId::DateTimeZoneId( const ConstDateTimeZoneId &date_time_zone_id) : ptr_(mg_date_time_zone_id_copy(date_time_zone_id.ptr())) {} inline ConstDateTimeZoneId DateTimeZoneId::AsConstDateTimeZoneId() const { return ConstDateTimeZoneId(ptr_); } inline bool DateTimeZoneId::operator==(const DateTimeZoneId &other) const { return detail::AreDateTimeZoneIdsEqual(ptr_, other.ptr_); } inline bool DateTimeZoneId::operator==(const ConstDateTimeZoneId &other) const { return detail::AreDateTimeZoneIdsEqual(ptr_, other.ptr()); } inline bool ConstDateTimeZoneId::operator==( const ConstDateTimeZoneId &other) const { return detail::AreDateTimeZoneIdsEqual(const_ptr_, other.const_ptr_); } inline bool ConstDateTimeZoneId::operator==(const DateTimeZoneId &other) const { return detail::AreDateTimeZoneIdsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // LocalDateTime: inline LocalDateTime::LocalDateTime(const LocalDateTime &other) : ptr_(mg_local_date_time_copy(other.ptr_)) {} inline LocalDateTime::LocalDateTime(LocalDateTime &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline LocalDateTime &LocalDateTime::operator=(const LocalDateTime &other) { ptr_ = mg_local_date_time_copy(other.ptr_); return *this; } inline LocalDateTime &LocalDateTime::operator=(LocalDateTime &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline LocalDateTime::~LocalDateTime() { if (ptr_ != nullptr) { mg_local_date_time_destroy(ptr_); } } inline LocalDateTime::LocalDateTime(const ConstLocalDateTime &local_date_time) : ptr_(mg_local_date_time_copy(local_date_time.ptr())) {} inline ConstLocalDateTime LocalDateTime::AsConstLocalDateTime() const { return ConstLocalDateTime(ptr_); } inline bool LocalDateTime::operator==(const LocalDateTime &other) const { return detail::AreLocalDateTimesEqual(ptr_, other.ptr_); } inline bool LocalDateTime::operator==(const ConstLocalDateTime &other) const { return detail::AreLocalDateTimesEqual(ptr_, other.ptr()); } inline bool ConstLocalDateTime::operator==( const ConstLocalDateTime &other) const { return detail::AreLocalDateTimesEqual(const_ptr_, other.const_ptr_); } inline bool ConstLocalDateTime::operator==(const LocalDateTime &other) const { return detail::AreLocalDateTimesEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Duration: inline Duration::Duration(const Duration &other) : ptr_(mg_duration_copy(other.ptr_)) {} inline Duration::Duration(Duration &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Duration &Duration::operator=(const Duration &other) { ptr_ = mg_duration_copy(other.ptr_); return *this; } inline Duration &Duration::operator=(Duration &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline Duration::~Duration() { if (ptr_ != nullptr) { mg_duration_destroy(ptr_); } } inline Duration::Duration(const ConstDuration &duration) : ptr_(mg_duration_copy(duration.ptr())) {} inline ConstDuration Duration::AsConstDuration() const { return ConstDuration(ptr_); } inline bool Duration::operator==(const Duration &other) const { return detail::AreDurationsEqual(ptr_, other.ptr_); } inline bool Duration::operator==(const ConstDuration &other) const { return detail::AreDurationsEqual(ptr_, other.ptr()); } inline bool ConstDuration::operator==(const ConstDuration &other) const { return detail::AreDurationsEqual(const_ptr_, other.const_ptr_); } inline bool ConstDuration::operator==(const Duration &other) const { return detail::AreDurationsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Point2d: inline Point2d::Point2d(const Point2d &other) : ptr_(mg_point_2d_copy(other.ptr_)) {} inline Point2d::Point2d(Point2d &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Point2d &Point2d::operator=(const Point2d &other) { ptr_ = mg_point_2d_copy(other.ptr_); return *this; } inline Point2d &Point2d::operator=(Point2d &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline Point2d::~Point2d() { if (ptr_ != nullptr) { mg_point_2d_destroy(ptr_); } } inline Point2d::Point2d(const ConstPoint2d &point_2d) : ptr_(mg_point_2d_copy(point_2d.ptr())) {} inline ConstPoint2d Point2d::AsConstPoint2d() const { return ConstPoint2d(ptr_); } inline bool Point2d::operator==(const Point2d &other) const { return detail::ArePoint2dsEqual(ptr_, other.ptr_); } inline bool Point2d::operator==(const ConstPoint2d &other) const { return detail::ArePoint2dsEqual(ptr_, other.ptr()); } inline bool ConstPoint2d::operator==(const ConstPoint2d &other) const { return detail::ArePoint2dsEqual(const_ptr_, other.const_ptr_); } inline bool ConstPoint2d::operator==(const Point2d &other) const { return detail::ArePoint2dsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Point3d: inline Point3d::Point3d(const Point3d &other) : ptr_(mg_point_3d_copy(other.ptr_)) {} inline Point3d::Point3d(Point3d &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Point3d &Point3d::operator=(const Point3d &other) { ptr_ = mg_point_3d_copy(other.ptr_); return *this; } inline Point3d &Point3d::operator=(Point3d &&other) { ptr_ = other.ptr_; other.ptr_ = nullptr; return *this; } inline Point3d::~Point3d() { if (ptr_ != nullptr) { mg_point_3d_destroy(ptr_); } } inline Point3d::Point3d(const ConstPoint3d &point_3d) : ptr_(mg_point_3d_copy(point_3d.ptr())) {} inline ConstPoint3d Point3d::AsConstPoint3d() const { return ConstPoint3d(ptr_); } inline bool Point3d::operator==(const Point3d &other) const { return detail::ArePoint3dsEqual(ptr_, other.ptr_); } inline bool Point3d::operator==(const ConstPoint3d &other) const { return detail::ArePoint3dsEqual(ptr_, other.ptr()); } inline bool ConstPoint3d::operator==(const ConstPoint3d &other) const { return detail::ArePoint3dsEqual(const_ptr_, other.const_ptr_); } inline bool ConstPoint3d::operator==(const Point3d &other) const { return detail::ArePoint3dsEqual(const_ptr_, other.ptr()); } //////////////////////////////////////////////////////////////////////////////// // Value: inline Value::Value(const Value &other) : Value(mg_value_copy(other.ptr_)) {} inline Value::Value(Value &&other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } inline Value::~Value() { if (ptr_ != nullptr) { mg_value_destroy(ptr_); } } inline Value::Value(const ConstValue &value) : ptr_(mg_value_copy(value.ptr())) {} inline Value::Value(const std::string_view value) : Value( mg_value_make_string2(mg_string_make2(value.size(), value.data()))) {} inline Value::Value(const char *value) : Value(mg_value_make_string(value)) {} inline Value::Value(List &&list) : Value(mg_value_make_list(list.ptr_)) { list.ptr_ = nullptr; } inline Value::Value(Map &&map) : Value(mg_value_make_map(map.ptr_)) { map.ptr_ = nullptr; } inline Value::Value(Node &&vertex) : Value(mg_value_make_node(vertex.ptr_)) { vertex.ptr_ = nullptr; } inline Value::Value(Relationship &&edge) : Value(mg_value_make_relationship(edge.ptr_)) { edge.ptr_ = nullptr; } inline Value::Value(UnboundRelationship &&edge) : Value(mg_value_make_unbound_relationship(edge.ptr_)) { edge.ptr_ = nullptr; } inline Value::Value(Path &&path) : Value(mg_value_make_path(path.ptr_)) { path.ptr_ = nullptr; } inline Value::Value(Date &&date) : Value(mg_value_make_date(date.ptr_)) { date.ptr_ = nullptr; } inline Value::Value(Time &&time) : Value(mg_value_make_time(time.ptr_)) { time.ptr_ = nullptr; } inline Value::Value(LocalTime &&local_time) : Value(mg_value_make_local_time(local_time.ptr_)) { local_time.ptr_ = nullptr; } inline Value::Value(DateTime &&date_time) : Value(mg_value_make_date_time(date_time.ptr_)) { date_time.ptr_ = nullptr; } inline Value::Value(DateTimeZoneId &&date_time_zone_id) : Value(mg_value_make_date_time_zone_id(date_time_zone_id.ptr_)) { date_time_zone_id.ptr_ = nullptr; } inline Value::Value(LocalDateTime &&local_date_time) : Value(mg_value_make_local_date_time(local_date_time.ptr_)) { local_date_time.ptr_ = nullptr; } inline Value::Value(Duration &&duration) : Value(mg_value_make_duration(duration.ptr_)) { duration.ptr_ = nullptr; } inline Value::Value(Point2d &&point_2d) : Value(mg_value_make_point_2d(point_2d.ptr_)) { point_2d.ptr_ = nullptr; } inline Value::Value(Point3d &&point_3d) : Value(mg_value_make_point_3d(point_3d.ptr_)) { point_3d.ptr_ = nullptr; } inline bool Value::ValueBool() const { if (type() != Type::Bool) { std::abort(); } return static_cast(mg_value_bool(ptr_)); } inline int64_t Value::ValueInt() const { if (type() != Type::Int) { std::abort(); } return mg_value_integer(ptr_); } inline double Value::ValueDouble() const { if (type() != Type::Double) { std::abort(); } return mg_value_float(ptr_); } inline std::string_view Value::ValueString() const { if (type() != Type::String) { std::abort(); } return detail::ConvertString(mg_value_string(ptr_)); } inline const ConstList Value::ValueList() const { if (type() != Type::List) { std::abort(); } return ConstList(mg_value_list(ptr_)); } inline const ConstMap Value::ValueMap() const { if (type() != Type::Map) { std::abort(); } return ConstMap(mg_value_map(ptr_)); } inline const ConstNode Value::ValueNode() const { if (type() != Type::Node) { std::abort(); } return ConstNode(mg_value_node(ptr_)); } inline const ConstRelationship Value::ValueRelationship() const { if (type() != Type::Relationship) { std::abort(); } return ConstRelationship(mg_value_relationship(ptr_)); } inline const ConstUnboundRelationship Value::ValueUnboundRelationship() const { if (type() != Type::UnboundRelationship) { std::abort(); } return ConstUnboundRelationship(mg_value_unbound_relationship(ptr_)); } inline const ConstPath Value::ValuePath() const { if (type() != Type::Path) { std::abort(); } return ConstPath(mg_value_path(ptr_)); } inline const ConstDate Value::ValueDate() const { if (type() != Type::Date) { std::abort(); } return ConstDate(mg_value_date(ptr_)); } inline const ConstTime Value::ValueTime() const { if (type() != Type::Time) { std::abort(); } return ConstTime(mg_value_time(ptr_)); } inline const ConstLocalTime Value::ValueLocalTime() const { if (type() != Type::LocalTime) { std::abort(); } return ConstLocalTime(mg_value_local_time(ptr_)); } inline const ConstDateTime Value::ValueDateTime() const { if (type() != Type::DateTime) { std::abort(); } return ConstDateTime(mg_value_date_time(ptr_)); } inline const ConstDateTimeZoneId Value::ValueDateTimeZoneId() const { if (type() != Type::DateTimeZoneId) { std::abort(); } return ConstDateTimeZoneId(mg_value_date_time_zone_id(ptr_)); } inline const ConstLocalDateTime Value::ValueLocalDateTime() const { if (type() != Type::LocalDateTime) { std::abort(); } return ConstLocalDateTime(mg_value_local_date_time(ptr_)); } inline const ConstDuration Value::ValueDuration() const { if (type() != Type::Duration) { std::abort(); } return ConstDuration(mg_value_duration(ptr_)); } inline const ConstPoint2d Value::ValuePoint2d() const { if (type() != Type::Point2d) { std::abort(); } return ConstPoint2d(mg_value_point_2d(ptr_)); } inline const ConstPoint3d Value::ValuePoint3d() const { if (type() != Type::Point3d) { std::abort(); } return ConstPoint3d(mg_value_point_3d(ptr_)); } inline Value::Type Value::type() const { return detail::ConvertType(mg_value_get_type(ptr_)); } inline ConstValue Value::AsConstValue() const { return ConstValue(ptr_); } inline bool Value::operator==(const Value &other) const { return detail::AreValuesEqual(ptr_, other.ptr_); } inline bool Value::operator==(const ConstValue &other) const { return detail::AreValuesEqual(ptr_, other.ptr()); } inline bool ConstValue::ValueBool() const { if (type() != Value::Type::Bool) { std::abort(); } return static_cast(mg_value_bool(const_ptr_)); } inline int64_t ConstValue::ValueInt() const { if (type() != Value::Type::Int) { std::abort(); } return mg_value_integer(const_ptr_); } inline double ConstValue::ValueDouble() const { if (type() != Value::Type::Double) { std::abort(); } return mg_value_float(const_ptr_); } inline std::string_view ConstValue::ValueString() const { if (type() != Value::Type::String) { std::abort(); } return detail::ConvertString(mg_value_string(const_ptr_)); } inline const ConstList ConstValue::ValueList() const { if (type() != Value::Type::List) { std::abort(); } return ConstList(mg_value_list(const_ptr_)); } inline const ConstMap ConstValue::ValueMap() const { if (type() != Value::Type::Map) { std::abort(); } return ConstMap(mg_value_map(const_ptr_)); } inline const ConstNode ConstValue::ValueNode() const { if (type() != Value::Type::Node) { std::abort(); } return ConstNode(mg_value_node(const_ptr_)); } inline const ConstRelationship ConstValue::ValueRelationship() const { if (type() != Value::Type::Relationship) { std::abort(); } return ConstRelationship(mg_value_relationship(const_ptr_)); } inline const ConstUnboundRelationship ConstValue::ValueUnboundRelationship() const { if (type() != Value::Type::UnboundRelationship) { std::abort(); } return ConstUnboundRelationship(mg_value_unbound_relationship(const_ptr_)); } inline const ConstPath ConstValue::ValuePath() const { if (type() != Value::Type::Path) { std::abort(); } return ConstPath(mg_value_path(const_ptr_)); } inline Value::Type ConstValue::type() const { return detail::ConvertType(mg_value_get_type(const_ptr_)); } inline const ConstDate ConstValue::ValueDate() const { if (type() != Value::Type::Date) { std::abort(); } return ConstDate(mg_value_date(const_ptr_)); } inline const ConstTime ConstValue::ValueTime() const { if (type() != Value::Type::Time) { std::abort(); } return ConstTime(mg_value_time(const_ptr_)); } inline const ConstLocalTime ConstValue::ValueLocalTime() const { if (type() != Value::Type::LocalTime) { std::abort(); } return ConstLocalTime(mg_value_local_time(const_ptr_)); } inline const ConstDateTime ConstValue::ValueDateTime() const { if (type() != Value::Type::DateTime) { std::abort(); } return ConstDateTime(mg_value_date_time(const_ptr_)); } inline const ConstDateTimeZoneId ConstValue::ValueDateTimeZoneId() const { if (type() != Value::Type::DateTimeZoneId) { std::abort(); } return ConstDateTimeZoneId(mg_value_date_time_zone_id(const_ptr_)); } inline const ConstLocalDateTime ConstValue::ValueLocalDateTime() const { if (type() != Value::Type::LocalDateTime) { std::abort(); } return ConstLocalDateTime(mg_value_local_date_time(const_ptr_)); } inline const ConstDuration ConstValue::ValueDuration() const { if (type() != Value::Type::Duration) { std::abort(); } return ConstDuration(mg_value_duration(const_ptr_)); } inline const ConstPoint2d ConstValue::ValuePoint2d() const { if (type() != Value::Type::Point2d) { std::abort(); } return ConstPoint2d(mg_value_point_2d(const_ptr_)); } inline const ConstPoint3d ConstValue::ValuePoint3d() const { if (type() != Value::Type::Point3d) { std::abort(); } return ConstPoint3d(mg_value_point_3d(const_ptr_)); } inline bool ConstValue::operator==(const ConstValue &other) const { return detail::AreValuesEqual(const_ptr_, other.const_ptr_); } inline bool ConstValue::operator==(const Value &other) const { return detail::AreValuesEqual(const_ptr_, other.ptr()); } } // namespace mg