Skip to content

Commit 4fb1c4b

Browse files
StarJiaojbeder
authored andcommitted
Enable items to be removed from a sequence (#582)
1 parent ab5f925 commit 4fb1c4b

5 files changed

Lines changed: 104 additions & 18 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
build/
2+
/tags

include/yaml-cpp/node/detail/impl.h

Lines changed: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct get_idx<Key,
3232

3333
static node* get(std::vector<node*>& sequence, const Key& key,
3434
shared_memory_holder pMemory) {
35-
if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined()))
35+
if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined()))
3636
return 0;
3737
if (key == sequence.size())
3838
sequence.push_back(&pMemory->create_node());
@@ -56,6 +56,37 @@ struct get_idx<Key, typename std::enable_if<std::is_signed<Key>::value>::type> {
5656
}
5757
};
5858

59+
template <typename Key, typename Enable = void>
60+
struct remove_idx {
61+
static bool remove(std::vector<node*>&, const Key&) { return false; }
62+
};
63+
64+
template <typename Key>
65+
struct remove_idx<
66+
Key, typename std::enable_if<std::is_unsigned<Key>::value &&
67+
!std::is_same<Key, bool>::value>::type> {
68+
69+
static bool remove(std::vector<node*>& sequence, const Key& key) {
70+
if (key >= sequence.size()) {
71+
return false;
72+
} else {
73+
sequence.erase(sequence.begin() + key);
74+
return true;
75+
}
76+
}
77+
};
78+
79+
template <typename Key>
80+
struct remove_idx<Key,
81+
typename std::enable_if<std::is_signed<Key>::value>::type> {
82+
83+
static bool remove(std::vector<node*>& sequence, const Key& key) {
84+
return key >= 0 ? remove_idx<std::size_t>::remove(
85+
sequence, static_cast<std::size_t>(key))
86+
: false;
87+
}
88+
};
89+
5990
template <typename T>
6091
inline bool node::equals(const T& rhs, shared_memory_holder pMemory) {
6192
T lhs;
@@ -129,21 +160,23 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) {
129160

130161
template <typename Key>
131162
inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) {
132-
if (m_type != NodeType::Map)
133-
return false;
134-
135-
for (kv_pairs::iterator it = m_undefinedPairs.begin();
136-
it != m_undefinedPairs.end();) {
137-
kv_pairs::iterator jt = std::next(it);
138-
if (it->first->equals(key, pMemory))
139-
m_undefinedPairs.erase(it);
140-
it = jt;
141-
}
163+
if (m_type == NodeType::Sequence) {
164+
return remove_idx<Key>::remove(m_sequence, key);
165+
} else if (m_type == NodeType::Map) {
166+
kv_pairs::iterator it = m_undefinedPairs.begin();
167+
while (it != m_undefinedPairs.end()) {
168+
kv_pairs::iterator jt = std::next(it);
169+
if (it->first->equals(key, pMemory)) {
170+
m_undefinedPairs.erase(it);
171+
}
172+
it = jt;
173+
}
142174

143-
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
144-
if (it->first->equals(key, pMemory)) {
145-
m_map.erase(it);
146-
return true;
175+
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
176+
if (it->first->equals(key, pMemory)) {
177+
m_map.erase(it);
178+
return true;
179+
}
147180
}
148181
}
149182

src/node_data.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,14 @@ bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
235235
if (m_type != NodeType::Map)
236236
return false;
237237

238+
kv_pairs::iterator it = m_undefinedPairs.begin();
239+
while (it != m_undefinedPairs.end()) {
240+
kv_pairs::iterator jt = std::next(it);
241+
if (it->first->is(key))
242+
m_undefinedPairs.erase(it);
243+
it = jt;
244+
}
245+
238246
for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) {
239247
if (it->first->is(key)) {
240248
m_map.erase(it);

test/node/node_test.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1+
#include "yaml-cpp/node/node.h"
12
#include "yaml-cpp/emitter.h"
3+
#include "yaml-cpp/node/convert.h"
4+
#include "yaml-cpp/node/detail/impl.h"
25
#include "yaml-cpp/node/emit.h"
3-
#include "yaml-cpp/node/node.h"
46
#include "yaml-cpp/node/impl.h"
5-
#include "yaml-cpp/node/convert.h"
67
#include "yaml-cpp/node/iterator.h"
7-
#include "yaml-cpp/node/detail/impl.h"
88

99
#include "gmock/gmock.h"
1010
#include "gtest/gtest.h"
@@ -47,13 +47,47 @@ TEST(NodeTest, SimpleAppendSequence) {
4747
EXPECT_TRUE(node.IsSequence());
4848
}
4949

50+
TEST(NodeTest, SequenceElementRemoval) {
51+
Node node;
52+
node[0] = "a";
53+
node[1] = "b";
54+
node[2] = "c";
55+
node.remove(1);
56+
EXPECT_TRUE(node.IsSequence());
57+
EXPECT_EQ(2, node.size());
58+
EXPECT_EQ("a", node[0].as<std::string>());
59+
EXPECT_EQ("c", node[1].as<std::string>());
60+
}
61+
62+
TEST(NodeTest, SequenceLastElementRemoval) {
63+
Node node;
64+
node[0] = "a";
65+
node[1] = "b";
66+
node[2] = "c";
67+
node.remove(2);
68+
EXPECT_TRUE(node.IsSequence());
69+
EXPECT_EQ(2, node.size());
70+
EXPECT_EQ("a", node[0].as<std::string>());
71+
EXPECT_EQ("b", node[1].as<std::string>());
72+
}
73+
5074
TEST(NodeTest, MapElementRemoval) {
5175
Node node;
5276
node["foo"] = "bar";
5377
node.remove("foo");
5478
EXPECT_TRUE(!node["foo"]);
5579
}
5680

81+
TEST(NodeTest, MapIntegerElementRemoval) {
82+
Node node;
83+
node[1] = "hello";
84+
node[2] = 'c';
85+
node["foo"] = "bar";
86+
EXPECT_TRUE(node.IsMap());
87+
node.remove(1);
88+
EXPECT_TRUE(node.IsMap());
89+
}
90+
5791
TEST(NodeTest, SimpleAssignSequence) {
5892
Node node;
5993
node[0] = 10;
@@ -106,6 +140,14 @@ TEST(NodeTest, RemoveUnassignedNode) {
106140
EXPECT_EQ(0, node.size());
107141
}
108142

143+
TEST(NodeTest, RemoveUnassignedNodeFromMap) {
144+
Node node(NodeType::Map);
145+
Node n;
146+
node[n];
147+
node.remove(n);
148+
EXPECT_EQ(0, node.size());
149+
}
150+
109151
TEST(NodeTest, MapForceInsert) {
110152
Node node;
111153
Node k1("k1");

util/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
13
add_sources(parse.cpp)
24
add_executable(parse parse.cpp)
35
target_link_libraries(parse yaml-cpp)

0 commit comments

Comments
 (0)