diff --git a/.gitignore b/.gitignore index 567609b..0e29154 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ build/ +/tags diff --git a/CMakeLists.txt b/CMakeLists.txt index d2d8810..2a32291 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -350,9 +350,9 @@ endif() ### ### Extras ### -if(YAML_CPP_BUILD_TESTS) - add_subdirectory(test) -endif() +###if(YAML_CPP_BUILD_TESTS) +### add_subdirectory(test) +###endif() if(YAML_CPP_BUILD_TOOLS) add_subdirectory(util) endif() diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h index 09e55f8..4b082fe 100644 --- a/include/yaml-cpp/node/detail/impl.h +++ b/include/yaml-cpp/node/detail/impl.h @@ -32,7 +32,7 @@ struct get_idx& sequence, const Key& key, shared_memory_holder pMemory) { - if (key > sequence.size() || (key > 0 && !sequence[key-1]->is_defined())) + if (key > sequence.size() || (key > 0 && !sequence[key - 1]->is_defined())) return 0; if (key == sequence.size()) sequence.push_back(&pMemory->create_node()); @@ -56,6 +56,40 @@ struct get_idx::value>::type> { } }; +template +struct remove_idx { + static char remove(std::vector& /* sequence */, const Key& /* key */) { + std::cout << __FILE__ << __LINE__ << std::endl; + return 0; + } +}; + +template +struct remove_idx< + Key, typename std::enable_if::value && + !std::is_same::value>::type> { + + static char remove(std::vector& sequence, const Key& key) { + if (key >= sequence.size()) { + return 0; + } else { + sequence.erase(sequence.begin() + key); + return 1; + } + } +}; + +template +struct remove_idx::value>::type> { + + static char remove(std::vector& sequence, const Key& key) { + return key >= 0 ? remove_idx::remove( + sequence, static_cast(key)) + : 0; + } +}; + template inline bool node::equals(const T& rhs, shared_memory_holder pMemory) { T lhs; @@ -129,23 +163,29 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { template inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { - if (m_type != NodeType::Map) - return false; + if (m_type == NodeType::Sequence) { + char result = remove_idx::remove(m_sequence, key); + if (result == 0) return false; + if (result == 1) return true; + convert_to_map(pMemory); + } + if (m_type == NodeType::Map) { - for (kv_pairs::iterator it = m_undefinedPairs.begin(); - it != m_undefinedPairs.end();) { - kv_pairs::iterator jt = std::next(it); - if (it->first->equals(key, pMemory)) - m_undefinedPairs.erase(it); - it = jt; - } + 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; - } - } + 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; } diff --git a/src/node_data.cpp b/src/node_data.cpp index 77cd465..2dfcd7b 100644 --- a/src/node_data.cpp +++ b/src/node_data.cpp @@ -235,6 +235,14 @@ bool node_data::remove(node& 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->is(key)) + m_undefinedPairs.erase(it); + it = jt; + } + for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { if (it->first->is(key)) { m_map.erase(it); diff --git a/test/node/node_test.cpp b/test/node/node_test.cpp index 485ad09..45ce0ed 100644 --- a/test/node/node_test.cpp +++ b/test/node/node_test.cpp @@ -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.IsSequence()); + EXPECT_EQ(2, node.size()); + EXPECT_EQ("a", node[0].as()); + EXPECT_EQ("c", node[2].as()); +} + +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()); + EXPECT_EQ("b", node[1].as()); +} + TEST(NodeTest, MapElementRemoval) { Node node; node["foo"] = "bar"; @@ -106,6 +130,14 @@ TEST(NodeTest, RemoveUnassignedNode) { EXPECT_EQ(0, node.size()); } +TEST(NodeTest, RemoveUnassignedNodeFromMap) { + Node node(NodeType::Map); + Node n; + node[n]; + node.remove(n); + EXPECT_EQ(0, node.size()); +} + TEST(NodeTest, MapForceInsert) { Node node; Node k1("k1"); diff --git a/util/CMakeLists.txt b/util/CMakeLists.txt index 2286627..0f6b500 100644 --- a/util/CMakeLists.txt +++ b/util/CMakeLists.txt @@ -1,3 +1,5 @@ +cmake_minimum_required(VERSION 3.5) + add_sources(parse.cpp) add_executable(parse parse.cpp) target_link_libraries(parse yaml-cpp) @@ -12,3 +14,8 @@ add_sources(read.cpp) add_executable(read read.cpp) target_link_libraries(read yaml-cpp) set_target_properties(read PROPERTIES COMPILE_FLAGS "-std=c++11") + +add_sources(demo.cpp) +add_executable(demo demo.cpp) +target_link_libraries(demo yaml-cpp) +set_target_properties(demo PROPERTIES COMPILE_FLAGS "-std=c++11") diff --git a/util/demo.cpp b/util/demo.cpp new file mode 100644 index 0000000..66e3567 --- /dev/null +++ b/util/demo.cpp @@ -0,0 +1,45 @@ +#include "yaml-cpp/yaml.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace YAML; +int main(){ + Node root; + + //rooe[0] = 2; + //root[1] = 5; + //root[2] = 77; + //root[3] = 324; + + + root[0] = 'f'; + root[1] = 'u'; + root[2] = 'c'; + root[3] = 'k'; + + + if(root.IsSequence()){ + cout << "sequence" << endl; + cout << root << endl; + } + + if(root.remove(1)){ + cout << "remove success" << endl; + } + + if(root.IsMap()){ + cout << "map" << endl; + } + + if(root.IsSequence()){ + cout << "sequence" << endl; + } + + cout << root << endl; + + return 0; +}