Add removing items from a sequence (#190)

This commit is contained in:
butataatawa 2017-02-18 15:56:40 +01:00
parent 4329bb7c02
commit 65c841fa2e
2 changed files with 81 additions and 15 deletions

View File

@ -56,6 +56,41 @@ struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
}
};
template <typename Key, typename Enable = void>
struct remove_idx {
static char remove(std::vector<node*>& /* sequence */, const Key& /* key */) {
return 0;
}
};
template <typename Key>
struct remove_idx<
Key, typename std::enable_if<std::is_unsigned<Key>::value &&
!std::is_same<Key, bool>::value>::type> {
static char remove(std::vector<node*>& sequence, const Key& key) {
if (key >= sequence.size() || !sequence[key]->is_defined())
return 0;
if (key + 1 == sequence.size()) {
sequence.pop_back();
return 1;
}
return 2;
}
};
template <typename Key>
struct remove_idx<Key,
typename std::enable_if<std::is_signed<Key>::value>::type> {
static char remove(std::vector<node*>& sequence, const Key& key) {
return key >= 0 ? remove_idx<std::size_t>::remove(
sequence, static_cast<std::size_t>(key))
: 0;
}
};
template <typename T>
inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
T lhs;
@ -129,24 +164,31 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
template <typename Key>
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
if (m_type != NodeType::Map)
return false;
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = std::next(it);
if (it->first->equals(key, pMemory))
m_undefinedPairs.erase(it);
it = jt;
}
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->equals(key, pMemory)) {
m_map.erase(it);
if (m_type == NodeType::Sequence) {
char result = remove_idx<Key>::remove(m_sequence, key);
if (result == 0)
return false;
if (result == 1)
return true;
convert_to_map(pMemory);
}
if (m_type == NodeType::Map) {
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
kv_pairs::iterator jt = std::next(it);
if (it->first->equals(key, pMemory))
m_undefinedPairs.erase(it);
it = jt;
}
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
if (it->first->equals(key, pMemory)) {
m_map.erase(it);
return true;
}
}
}
return false;
}

View File

@ -47,6 +47,30 @@ TEST(NodeTest, SimpleAppendSequence) {
EXPECT_TRUE(node.IsSequence());
}
TEST(NodeTest, SequenceElementRemoval) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
node.remove(1);
EXPECT_TRUE(node.IsMap());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("c", node[2].as<std::string>());
}
TEST(NodeTest, SequenceLastElementRemoval) {
Node node;
node[0] = "a";
node[1] = "b";
node[2] = "c";
node.remove(2);
EXPECT_TRUE(node.IsSequence());
EXPECT_EQ(2, node.size());
EXPECT_EQ("a", node[0].as<std::string>());
EXPECT_EQ("b", node[1].as<std::string>());
}
TEST(NodeTest, MapElementRemoval) {
Node node;
node["foo"] = "bar";