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);
|
||||
}
|
||||
|
||||
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 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.
|
||||
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.
|
||||
/// Current implementation always returns without errors.
|
||||
enum mgp_error mgp_map_size(struct mgp_map *map, size_t *result);
|
||||
|
@ -464,6 +464,7 @@ class Map {
|
||||
public:
|
||||
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
||||
explicit Map(mgp_map *ptr);
|
||||
|
||||
/// @brief Creates a Map from the copy of the given @ref mgp_map.
|
||||
explicit Map(const mgp_map *const_ptr);
|
||||
|
||||
@ -472,6 +473,7 @@ class Map {
|
||||
|
||||
/// @brief Creates a Map from the given vector.
|
||||
explicit Map(const std::map<std::string_view, Value> &items);
|
||||
|
||||
/// @brief Creates a Map from the given vector.
|
||||
explicit Map(std::map<std::string_view, Value> &&items);
|
||||
|
||||
@ -488,11 +490,13 @@ class Map {
|
||||
|
||||
/// @brief Returns the size of the map.
|
||||
size_t Size() const;
|
||||
|
||||
/// @brief Returns whether the map is empty.
|
||||
bool Empty() const;
|
||||
|
||||
/// @brief Returns the value at the given `key`.
|
||||
Value const operator[](std::string_view key) const;
|
||||
|
||||
/// @brief Returns the value at the given `key`.
|
||||
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.
|
||||
void Insert(std::string_view key, const Value &value);
|
||||
|
||||
/// @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
|
||||
/// operation is undefined.
|
||||
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)
|
||||
|
||||
/// @exception std::runtime_error Map contains value of unknown type.
|
||||
bool operator==(const Map &other) const;
|
||||
|
||||
/// @exception std::runtime_error Map contains value of unknown type.
|
||||
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) {
|
||||
mgp::map_insert(ptr_, key.data(), value.ptr_);
|
||||
value.~Value();
|
||||
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 !(*this == other); }
|
||||
@ -3438,7 +3467,6 @@ inline std::ostream &operator<<(std::ostream &os, const mgp::Type &type) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* #endregion */
|
||||
|
||||
/* #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) {
|
||||
static_assert(noexcept(map->items.size()));
|
||||
*result = map->items.size();
|
||||
|
@ -531,3 +531,34 @@ TYPED_TEST(CppApiTestFixture, TestTypeOperatorStream) {
|
||||
ASSERT_EQ(int_test, "int");
|
||||
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