Add mgp::map erase and update (#1103)
This commit is contained in:
parent
be4eb95a98
commit
3fd9ce4a33
@ -335,6 +335,12 @@ inline void map_insert(mgp_map *map, const char *key, mgp_value *value) {
|
|||||||
MgInvokeVoid(mgp_map_insert, map, key, value);
|
MgInvokeVoid(mgp_map_insert, map, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void map_update(mgp_map *map, const char *key, mgp_value *value) {
|
||||||
|
MgInvokeVoid(mgp_map_update, map, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void map_erase(mgp_map *map, const char *key) { MgInvokeVoid(mgp_map_erase, map, key); }
|
||||||
|
|
||||||
inline size_t map_size(mgp_map *map) { return MgInvoke<size_t>(mgp_map_size, map); }
|
inline size_t map_size(mgp_map *map) { return MgInvoke<size_t>(mgp_map_size, map); }
|
||||||
|
|
||||||
inline mgp_value *map_at(mgp_map *map, const char *key) { return MgInvoke<mgp_value *>(mgp_map_at, map, key); }
|
inline mgp_value *map_at(mgp_map *map, const char *key) { return MgInvoke<mgp_value *>(mgp_map_at, map, key); }
|
||||||
|
@ -462,6 +462,18 @@ void mgp_map_destroy(struct mgp_map *map);
|
|||||||
/// Return mgp_error::MGP_ERROR_KEY_ALREADY_EXISTS if a previous mapping already exists.
|
/// Return mgp_error::MGP_ERROR_KEY_ALREADY_EXISTS if a previous mapping already exists.
|
||||||
enum mgp_error mgp_map_insert(struct mgp_map *map, const char *key, struct mgp_value *value);
|
enum mgp_error mgp_map_insert(struct mgp_map *map, const char *key, struct mgp_value *value);
|
||||||
|
|
||||||
|
/// Insert a mapping from a NULL terminated character string to a value.
|
||||||
|
/// If a mapping with the same key already exists, it is replaced.
|
||||||
|
/// In case of update, both the string and the value are copied into the map.
|
||||||
|
/// Therefore, the map does not take ownership of the original key nor value, so
|
||||||
|
/// you still need to free their memory explicitly.
|
||||||
|
/// Return mgp_error::MGP_ERROR_UNABLE_TO_ALLOCATE is returned if unable to allocate for insertion.
|
||||||
|
enum mgp_error mgp_map_update(struct mgp_map *map, const char *key, struct mgp_value *value);
|
||||||
|
|
||||||
|
// Erase a mapping by key.
|
||||||
|
// If the key doesn't exist in the map nothing happens
|
||||||
|
enum mgp_error mgp_map_erase(struct mgp_map *map, const char *key);
|
||||||
|
|
||||||
/// Get the number of items stored in mgp_map.
|
/// Get the number of items stored in mgp_map.
|
||||||
/// Current implementation always returns without errors.
|
/// Current implementation always returns without errors.
|
||||||
enum mgp_error mgp_map_size(struct mgp_map *map, size_t *result);
|
enum mgp_error mgp_map_size(struct mgp_map *map, size_t *result);
|
||||||
|
@ -464,6 +464,7 @@ class Map {
|
|||||||
public:
|
public:
|
||||||
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
||||||
explicit Map(mgp_map *ptr);
|
explicit Map(mgp_map *ptr);
|
||||||
|
|
||||||
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
||||||
explicit Map(const mgp_map *const_ptr);
|
explicit Map(const mgp_map *const_ptr);
|
||||||
|
|
||||||
@ -472,6 +473,7 @@ class Map {
|
|||||||
|
|
||||||
/// @brief Creates a Map from the given vector.
|
/// @brief Creates a Map from the given vector.
|
||||||
explicit Map(const std::map<std::string_view, Value> &items);
|
explicit Map(const std::map<std::string_view, Value> &items);
|
||||||
|
|
||||||
/// @brief Creates a Map from the given vector.
|
/// @brief Creates a Map from the given vector.
|
||||||
explicit Map(std::map<std::string_view, Value> &&items);
|
explicit Map(std::map<std::string_view, Value> &&items);
|
||||||
|
|
||||||
@ -488,11 +490,13 @@ class Map {
|
|||||||
|
|
||||||
/// @brief Returns the size of the map.
|
/// @brief Returns the size of the map.
|
||||||
size_t Size() const;
|
size_t Size() const;
|
||||||
|
|
||||||
/// @brief Returns whether the map is empty.
|
/// @brief Returns whether the map is empty.
|
||||||
bool Empty() const;
|
bool Empty() const;
|
||||||
|
|
||||||
/// @brief Returns the value at the given `key`.
|
/// @brief Returns the value at the given `key`.
|
||||||
Value const operator[](std::string_view key) const;
|
Value const operator[](std::string_view key) const;
|
||||||
|
|
||||||
/// @brief Returns the value at the given `key`.
|
/// @brief Returns the value at the given `key`.
|
||||||
Value const At(std::string_view key) const;
|
Value const At(std::string_view key) const;
|
||||||
|
|
||||||
@ -533,16 +537,30 @@ class Map {
|
|||||||
|
|
||||||
/// @brief Inserts the given `key`-`value` pair into the map. The `value` is copied.
|
/// @brief Inserts the given `key`-`value` pair into the map. The `value` is copied.
|
||||||
void Insert(std::string_view key, const Value &value);
|
void Insert(std::string_view key, const Value &value);
|
||||||
|
|
||||||
/// @brief Inserts the given `key`-`value` pair into the map.
|
/// @brief Inserts the given `key`-`value` pair into the map.
|
||||||
/// @note Takes the ownership of `value` by moving it. The behavior of accessing `value` after performing this
|
/// @note Takes the ownership of `value` by moving it. The behavior of accessing `value` after performing this
|
||||||
/// operation is undefined.
|
/// operation is undefined.
|
||||||
void Insert(std::string_view key, Value &&value);
|
void Insert(std::string_view key, Value &&value);
|
||||||
|
|
||||||
// void Erase(std::string_view key); // not implemented (requires mgp_map_erase in the MGP API)
|
/// @brief Updates the `key`-`value` pair in the map. If the key doesn't exist, the value gets inserted. The `value`
|
||||||
|
/// is copied.
|
||||||
|
void Update(std::string_view key, const Value &value);
|
||||||
|
|
||||||
|
/// @brief Updates the `key`-`value` pair in the map. If the key doesn't exist, the value gets inserted. The `value`
|
||||||
|
/// is copied.
|
||||||
|
/// @note Takes the ownership of `value` by moving it. The behavior of accessing `value` after performing this
|
||||||
|
/// operation is undefined.
|
||||||
|
void Update(std::string_view key, Value &&value);
|
||||||
|
|
||||||
|
/// @brief Erases the element associated with the key from the map, if it doesn't exist does nothing.
|
||||||
|
void Erase(std::string_view key);
|
||||||
|
|
||||||
// void Clear(); // not implemented (requires mgp_map_clear in the MGP API)
|
// void Clear(); // not implemented (requires mgp_map_clear in the MGP API)
|
||||||
|
|
||||||
/// @exception std::runtime_error Map contains value of unknown type.
|
/// @exception std::runtime_error Map contains value of unknown type.
|
||||||
bool operator==(const Map &other) const;
|
bool operator==(const Map &other) const;
|
||||||
|
|
||||||
/// @exception std::runtime_error Map contains value of unknown type.
|
/// @exception std::runtime_error Map contains value of unknown type.
|
||||||
bool operator!=(const Map &other) const;
|
bool operator!=(const Map &other) const;
|
||||||
|
|
||||||
@ -2390,9 +2408,20 @@ inline void Map::Insert(std::string_view key, const Value &value) { mgp::map_ins
|
|||||||
|
|
||||||
inline void Map::Insert(std::string_view key, Value &&value) {
|
inline void Map::Insert(std::string_view key, Value &&value) {
|
||||||
mgp::map_insert(ptr_, key.data(), value.ptr_);
|
mgp::map_insert(ptr_, key.data(), value.ptr_);
|
||||||
|
value.~Value();
|
||||||
value.ptr_ = nullptr;
|
value.ptr_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Map::Update(std::string_view key, const Value &value) { mgp::map_update(ptr_, key.data(), value.ptr_); }
|
||||||
|
|
||||||
|
inline void Map::Update(std::string_view key, Value &&value) {
|
||||||
|
mgp::map_update(ptr_, key.data(), value.ptr_);
|
||||||
|
value.~Value();
|
||||||
|
value.ptr_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Map::Erase(std::string_view key) { mgp::map_erase(ptr_, key.data()); }
|
||||||
|
|
||||||
inline bool Map::operator==(const Map &other) const { return util::MapsEqual(ptr_, other.ptr_); }
|
inline bool Map::operator==(const Map &other) const { return util::MapsEqual(ptr_, other.ptr_); }
|
||||||
|
|
||||||
inline bool Map::operator!=(const Map &other) const { return !(*this == other); }
|
inline bool Map::operator!=(const Map &other) const { return !(*this == other); }
|
||||||
@ -3438,7 +3467,6 @@ inline std::ostream &operator<<(std::ostream &os, const mgp::Type &type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* #endregion */
|
/* #endregion */
|
||||||
|
|
||||||
/* #region Record */
|
/* #region Record */
|
||||||
|
@ -1043,6 +1043,25 @@ mgp_error mgp_map_insert(mgp_map *map, const char *key, mgp_value *value) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgp_error mgp_map_update(mgp_map *map, const char *key, mgp_value *value) {
|
||||||
|
return WrapExceptions([&] {
|
||||||
|
auto emplace_result = map->items.emplace(key, *value);
|
||||||
|
if (!emplace_result.second) {
|
||||||
|
map->items.erase(emplace_result.first);
|
||||||
|
map->items.emplace(key, *value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mgp_error mgp_map_erase(mgp_map *map, const char *key) {
|
||||||
|
return WrapExceptions([&] {
|
||||||
|
auto iterator = map->items.find(key);
|
||||||
|
if (iterator != map->items.end()) {
|
||||||
|
map->items.erase(iterator);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
mgp_error mgp_map_size(mgp_map *map, size_t *result) {
|
mgp_error mgp_map_size(mgp_map *map, size_t *result) {
|
||||||
static_assert(noexcept(map->items.size()));
|
static_assert(noexcept(map->items.size()));
|
||||||
*result = map->items.size();
|
*result = map->items.size();
|
||||||
|
@ -531,3 +531,34 @@ TYPED_TEST(CppApiTestFixture, TestTypeOperatorStream) {
|
|||||||
ASSERT_EQ(int_test, "int");
|
ASSERT_EQ(int_test, "int");
|
||||||
ASSERT_EQ(list_test, "list");
|
ASSERT_EQ(list_test, "list");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CppApiTestFixture, TestMapUpdate) {
|
||||||
|
mgp::Map map{};
|
||||||
|
mgp::Value double_1{1.0};
|
||||||
|
mgp::Value double_2{2.0};
|
||||||
|
|
||||||
|
map.Update("1", double_1);
|
||||||
|
ASSERT_EQ(map.At("1"), double_1);
|
||||||
|
|
||||||
|
map.Update("1", double_2);
|
||||||
|
ASSERT_EQ(map.At("1"), double_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TYPED_TEST(CppApiTestFixture, TestMapErase) {
|
||||||
|
mgp::Map map{};
|
||||||
|
mgp::Value double_1{1.0};
|
||||||
|
mgp::Value double_2{2.0};
|
||||||
|
|
||||||
|
map.Insert("1", double_1);
|
||||||
|
map.Insert("2", double_2);
|
||||||
|
ASSERT_EQ(map.Size(), 2);
|
||||||
|
|
||||||
|
map.Erase("1");
|
||||||
|
ASSERT_EQ(map.Size(), 1);
|
||||||
|
|
||||||
|
map.Erase("1");
|
||||||
|
ASSERT_EQ(map.Size(), 1);
|
||||||
|
|
||||||
|
map.Erase("2");
|
||||||
|
ASSERT_EQ(map.Size(), 0);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user