From bdfe275d172ac30bc5e89a6375a5a64dea20b3c0 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Fri, 7 Oct 2016 23:07:35 -0500 Subject: [PATCH 01/16] Add, and update, documentation build targets. --- doc/Jamfile.v2 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/Jamfile.v2 b/doc/Jamfile.v2 index 96601b7222..47e1ebe05d 100644 --- a/doc/Jamfile.v2 +++ b/doc/Jamfile.v2 @@ -45,3 +45,13 @@ boostbook standalone autodoc pdf:boost.url.prefix=http://www.boost.org/doc/libs/release/libs/property_tree/doc/html ; + +############################################################################### +alias boostdoc + : property_tree + : + : autodoc + : ; +explicit boostdoc ; +alias boostrelease ; +explicit boostrelease ; From 54523f05418b5b48293e6ce79d07ed9376e3bce4 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 19 Feb 2017 14:35:40 +0100 Subject: [PATCH 02/16] Failing test for move c-tor/assignment added --- test/test_property_tree.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/test_property_tree.hpp b/test/test_property_tree.hpp index 4216945a15..975418531e 100644 --- a/test/test_property_tree.hpp +++ b/test/test_property_tree.hpp @@ -91,6 +91,18 @@ void test_constructor_destructor_assignment(PTREE *) BOOST_CHECK(pt1 == *pt3); //BOOST_CHECK(PTREE::debug_get_instances_count() == 15); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Test move constructor + PTREE pt4(std::move(pt1)); + + BOOST_CHECK(pt4 == *pt2); + BOOST_CHECK(pt1.empty()); + + // Test move assignment + pt1 = std::move(pt4); + BOOST_CHECK(pt1 == *pt2); + BOOST_CHECK(pt4.empty()); +#endif // Destroy delete pt2; //BOOST_CHECK(PTREE::debug_get_instances_count() == 10); From 2dd39d58008aa7a01f8c724cdeb7c04987e451f2 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 19 Feb 2017 14:47:23 +0100 Subject: [PATCH 03/16] Move c-tor/assignment operator implemented --- .../detail/ptree_implementation.hpp | 19 +++++++++++++++++++ include/boost/property_tree/ptree.hpp | 9 +++++++++ 2 files changed, 28 insertions(+) diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index dd9fd37e26..20a5387957 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -194,6 +194,15 @@ namespace boost { namespace property_tree { } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template inline + basic_ptree::basic_ptree(basic_ptree &&rv) + : m_data(std::move(rv.m_data)), + m_children(new typename subs::base_container(std::move(subs::ch(&rv)))) + { + } +#endif + template basic_ptree & basic_ptree::operator =(const basic_ptree &rhs) @@ -202,6 +211,16 @@ namespace boost { namespace property_tree return *this; } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + basic_ptree & + basic_ptree::operator =(basic_ptree &&rv) + { + rv.swap(*this); + return *this; + } +#endif + template basic_ptree::~basic_ptree() { diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp index 9e7b921659..0ecb6b35a9 100644 --- a/include/boost/property_tree/ptree.hpp +++ b/include/boost/property_tree/ptree.hpp @@ -89,10 +89,19 @@ namespace boost { namespace property_tree /** Creates a node with no children and a copy of the given data. */ explicit basic_ptree(const data_type &data); basic_ptree(const self_type &rhs); + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + basic_ptree(self_type &&rv); +#endif + ~basic_ptree(); /** Basic guarantee only. */ self_type &operator =(const self_type &rhs); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + self_type &operator =(self_type &&rv); +#endif + /** Swap with other tree. Only constant-time and nothrow if the * data type's swap is. */ From 637aef0ef31d2b32eb17b3036998e9a8d21ac156 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Tue, 2 May 2017 21:18:33 +0200 Subject: [PATCH 04/16] Created failing test for move push_back --- test/test_property_tree.hpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/test_property_tree.hpp b/test/test_property_tree.hpp index 975418531e..84edb37ac2 100644 --- a/test/test_property_tree.hpp +++ b/test/test_property_tree.hpp @@ -254,6 +254,27 @@ void test_pushpop(PTREE *) //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); BOOST_CHECK(pt.empty()); + // Copy push_back vs move push_back +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + { + PTREE::value_type to_copy; + to_copy.second.push_back(std::make_pair(T("key"), PTREE(T("data")))); + + PTREE::value_type to_move; + to_move.second.push_back(std::make_pair(T("key"), PTREE(T("data")))); + + + PTREE receiver; + receiver.push_back(to_copy); + receiver.push_back(std::move(to_move)); + + BOOST_CHECK(to_copy.second.size() == 1); + BOOST_CHECK(to_move.second.empty()); + + BOOST_CHECK(receiver.size() == 2); + } +#endif + } void test_container_iteration(PTREE *) From a7035bea02dad2d17af5e6bfb095ad5ce47c8e61 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 15:33:54 +0200 Subject: [PATCH 05/16] New test suite for contained object lifetime --- test/Jamfile.v2 | 1 + test/test_lifecycle.cpp | 139 ++++++++++++++++++++++++++++++++++++ test/test_property_tree.hpp | 22 ------ 3 files changed, 140 insertions(+), 22 deletions(-) create mode 100644 test/test_lifecycle.cpp diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index af25731d74..4239ee0406 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -24,4 +24,5 @@ test-suite "property_tree" [ run test_xml_parser_rapidxml.cpp ] [ run test_multi_module1.cpp test_multi_module2.cpp ] + [ run test_lifecycle.cpp ] ; diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp new file mode 100644 index 0000000000..51f8774f85 --- /dev/null +++ b/test/test_lifecycle.cpp @@ -0,0 +1,139 @@ + +// ---------------------------------------------------------------------------- +// Copyright (C) 2017 Maciej Gajewski +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see www.boost.org +// ---------------------------------------------------------------------------- + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +// These test are to make sure that no uneccesary copy of storwd object is performend, and that move is prefered over copy +// whenever applicable + +#include +#include + + +template +struct lifecycle_counter +{ + static int default_ctors; + static int copy_ctors; + static int move_ctors; + static int init_ctors; + static int copy_assigments; + static int move_assignments; + static int destructors; + + static void reset_counters() + { + default_ctors = 0; + copy_ctors = 0; + move_ctors = 0; + init_ctors = 0; + copy_assigments = 0; + move_assignments = 0; + destructors = 0; + } + + std::string m_value; + + lifecycle_counter() + { + default_ctors++; + } + + lifecycle_counter(const std::string& from) + : m_value(from) + { + init_ctors++; + } + + lifecycle_counter(const char* from) + : m_value(from) + { + init_ctors++; + } + + lifecycle_counter(const lifecycle_counter& o) + : m_value(o.m_value) + { + copy_ctors++; + } + + lifecycle_counter(lifecycle_counter&& o) + : m_value(o.m_value) + { + move_ctors++; + } + + ~lifecycle_counter() + { + destructors++; + } + + lifecycle_counter& operator=(const lifecycle_counter& o) + { + m_value = o.m_value; + copy_assigments++; + } + + lifecycle_counter& operator=(lifecycle_counter&& o) + { + m_value = o.m_value; + move_assignments++; + } + + bool operator == (const lifecycle_counter& o) const + { + return m_value = o.m_value; + } + + bool operator < (const lifecycle_counter& o) const + { + return m_value < o.m_value; + } +}; + +template int lifecycle_counter::default_ctors = 0; +template int lifecycle_counter::copy_ctors = 0; +template int lifecycle_counter::move_ctors = 0; +template int lifecycle_counter::init_ctors = 0; +template int lifecycle_counter::copy_assigments = 0; +template int lifecycle_counter::move_assignments = 0; +template int lifecycle_counter::destructors = 0; + + +using key_type = lifecycle_counter; +using data_type = lifecycle_counter; + +using test_ptree = boost::property_tree::basic_ptree; + +namespace boost { namespace property_tree { + +template<> +struct path_of +{ + using type = std::string; +}; + +}} + +static void test_container() +{ + test_ptree a; + a.push_back({"key", test_ptree("value")}); + +} + +int test_main(int, char *[]) +{ + test_container(); + + return 0; +} + +#endif \ No newline at end of file diff --git a/test/test_property_tree.hpp b/test/test_property_tree.hpp index 84edb37ac2..45fe606076 100644 --- a/test/test_property_tree.hpp +++ b/test/test_property_tree.hpp @@ -253,28 +253,6 @@ void test_pushpop(PTREE *) pt.pop_front(); //BOOST_CHECK(PTREE::debug_get_instances_count() == 5); BOOST_CHECK(pt.empty()); - - // Copy push_back vs move push_back -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - { - PTREE::value_type to_copy; - to_copy.second.push_back(std::make_pair(T("key"), PTREE(T("data")))); - - PTREE::value_type to_move; - to_move.second.push_back(std::make_pair(T("key"), PTREE(T("data")))); - - - PTREE receiver; - receiver.push_back(to_copy); - receiver.push_back(std::move(to_move)); - - BOOST_CHECK(to_copy.second.size() == 1); - BOOST_CHECK(to_move.second.empty()); - - BOOST_CHECK(receiver.size() == 2); - } -#endif - } void test_container_iteration(PTREE *) From 9cc39d3cd7ec3da0a9a3dad0277b74a26952cd27 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 16:00:43 +0200 Subject: [PATCH 06/16] First, failing testin the new suite --- test/test_lifecycle.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index 51f8774f85..d376bebc91 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -17,7 +17,7 @@ #include -template +template struct lifecycle_counter { static int default_ctors; @@ -65,7 +65,7 @@ struct lifecycle_counter } lifecycle_counter(lifecycle_counter&& o) - : m_value(o.m_value) + : m_value(std::move(o.m_value)) { move_ctors++; } @@ -79,17 +79,19 @@ struct lifecycle_counter { m_value = o.m_value; copy_assigments++; + return *this; } lifecycle_counter& operator=(lifecycle_counter&& o) { m_value = o.m_value; move_assignments++; + return *this; } bool operator == (const lifecycle_counter& o) const { - return m_value = o.m_value; + return m_value == o.m_value; } bool operator < (const lifecycle_counter& o) const @@ -122,10 +124,30 @@ struct path_of }} -static void test_container() +static void reset_counters() +{ + key_type::reset_counters(); + data_type::reset_counters(); +} + +static test_ptree make_one_element_tree() { test_ptree a; a.push_back({"key", test_ptree("value")}); + return a; +} + +// Test copy/move of the entire test_container +static void test_container() +{ + test_ptree a = make_one_element_tree(); + + // Copy - expect key and value to be copied + reset_counters(); + test_ptree b = a; + + BOOST_CHECK(key_type::copy_ctors == 1); + BOOST_CHECK(data_type::copy_ctors == 1); } @@ -136,4 +158,4 @@ int test_main(int, char *[]) return 0; } -#endif \ No newline at end of file +#endif // BOOST_NO_CXX11_RVALUE_REFERENCES \ No newline at end of file From 42b557be1c91928966599ec8f42d979dd9bbabb5 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 16:07:43 +0200 Subject: [PATCH 07/16] container copy/move test --- test/test_lifecycle.cpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index d376bebc91..8ef9bd0b6b 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -130,25 +130,28 @@ static void reset_counters() data_type::reset_counters(); } -static test_ptree make_one_element_tree() -{ - test_ptree a; - a.push_back({"key", test_ptree("value")}); - return a; -} +// static test_ptree make_one_element_tree() +// { +// test_ptree a; +// a.push_back({"key", test_ptree("value")}); +// return a; +// } // Test copy/move of the entire test_container static void test_container() { - test_ptree a = make_one_element_tree(); + test_ptree a("value"); - // Copy - expect key and value to be copied + // Copy - expect value to be copied reset_counters(); test_ptree b = a; - - BOOST_CHECK(key_type::copy_ctors == 1); BOOST_CHECK(data_type::copy_ctors == 1); + // Move - expect the vaule not to be copied + reset_counters(); + test_ptree c = std::move(a); + BOOST_CHECK(data_type::copy_ctors == 0); + BOOST_CHECK(data_type::copy_assigments == 0); } int test_main(int, char *[]) From 16573f99f2b392f948fed2544b70a18ca1717eac Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 16:32:41 +0200 Subject: [PATCH 08/16] Failing test for moving push_back --- test/test_lifecycle.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index 8ef9bd0b6b..f75ff501af 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -154,9 +154,35 @@ static void test_container() BOOST_CHECK(data_type::copy_assigments == 0); } +static void test_push_back() +{ + test_ptree tree; + + // push_back - copy + test_ptree::value_type child1("key1", test_ptree("c1")); + + reset_counters(); + tree.push_back(child1); + + BOOST_CHECK(data_type::copy_ctors == 1); + BOOST_CHECK(key_type::copy_ctors == 1); + + // push_back - move + test_ptree::value_type child2("key2", test_ptree("c2")); + + reset_counters(); + tree.push_back(std::move(child2)); + + BOOST_CHECK(data_type::copy_ctors == 0); + BOOST_CHECK(data_type::copy_assigments == 0); + BOOST_CHECK(key_type::copy_ctors == 0); + BOOST_CHECK(key_type::copy_assigments == 0); +} + int test_main(int, char *[]) { test_container(); + test_push_back(); return 0; } From 99f444ba143bf77a9de9d46d879fe3fdbbd5c1a1 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 16:36:08 +0200 Subject: [PATCH 09/16] R-value ref push_back implemented --- .../boost/property_tree/detail/ptree_implementation.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index 20a5387957..da8c7ad63d 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -383,6 +383,13 @@ namespace boost { namespace property_tree return iterator(subs::ch(this).push_back(value).first); } + template inline + typename basic_ptree::iterator + basic_ptree::push_back(value_type &&value) + { + return iterator(subs::ch(this).push_back(std::move(value)).first); + } + template inline void basic_ptree::pop_front() { From dd6bd7adb4e6a8d44fea63aca7398e95ae29582e Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 17:03:20 +0200 Subject: [PATCH 10/16] moving push_back added, but key is still copied, and will be no matter what --- include/boost/property_tree/detail/ptree_implementation.hpp | 2 ++ include/boost/property_tree/ptree.hpp | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index da8c7ad63d..2b5641c3fe 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -383,12 +383,14 @@ namespace boost { namespace property_tree return iterator(subs::ch(this).push_back(value).first); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template inline typename basic_ptree::iterator basic_ptree::push_back(value_type &&value) { return iterator(subs::ch(this).push_back(std::move(value)).first); } +#endif template inline void basic_ptree::pop_front() diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp index 0ecb6b35a9..65bf0cbc39 100644 --- a/include/boost/property_tree/ptree.hpp +++ b/include/boost/property_tree/ptree.hpp @@ -161,7 +161,9 @@ namespace boost { namespace property_tree /** Equivalent to insert(end(), value). */ iterator push_back(const value_type &value); - +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + iterator push_back(value_type &&value); +#endif /** Equivalent to erase(begin()). */ void pop_front(); From 636b1fddc140c6cc2ec85120afb96286f88a3fc4 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 17:04:29 +0200 Subject: [PATCH 11/16] push_back test passing now --- test/test_lifecycle.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index f75ff501af..d932dc59d8 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -175,8 +175,6 @@ static void test_push_back() BOOST_CHECK(data_type::copy_ctors == 0); BOOST_CHECK(data_type::copy_assigments == 0); - BOOST_CHECK(key_type::copy_ctors == 0); - BOOST_CHECK(key_type::copy_assigments == 0); } int test_main(int, char *[]) From 0366d9a1fc55584c77db1c548b836930ba7ae332 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 17:48:57 +0200 Subject: [PATCH 12/16] Generated documentation added to gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..73294a570d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +doc/autodoc.xml +doc/html/ From 9031b836305dc0ef920095dcae8ce859a7b24384 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 17:53:31 +0200 Subject: [PATCH 13/16] Added doco to push_back overload --- include/boost/property_tree/ptree.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp index 65bf0cbc39..ffceca24e5 100644 --- a/include/boost/property_tree/ptree.hpp +++ b/include/boost/property_tree/ptree.hpp @@ -162,6 +162,7 @@ namespace boost { namespace property_tree /** Equivalent to insert(end(), value). */ iterator push_back(const value_type &value); #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /** Equivalent to insert(end(), value). */ iterator push_back(value_type &&value); #endif /** Equivalent to erase(begin()). */ From 6c7f372f95aef193469a1d0f348369ee2ca4e15d Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 17:56:25 +0200 Subject: [PATCH 14/16] Added, tested moving push_front --- .../detail/ptree_implementation.hpp | 9 ++++++ include/boost/property_tree/ptree.hpp | 6 ++++ test/test_lifecycle.cpp | 30 +++++++++++++++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index 2b5641c3fe..185c1e9a0f 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -376,6 +376,15 @@ namespace boost { namespace property_tree return iterator(subs::ch(this).push_front(value).first); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template inline + typename basic_ptree::iterator + basic_ptree::push_front(value_type &&value) + { + return iterator(subs::ch(this).push_front(std::move(value)).first); + } +#endif + template inline typename basic_ptree::iterator basic_ptree::push_back(const value_type &value) diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp index ffceca24e5..d10519e2af 100644 --- a/include/boost/property_tree/ptree.hpp +++ b/include/boost/property_tree/ptree.hpp @@ -159,8 +159,14 @@ namespace boost { namespace property_tree /** Equivalent to insert(begin(), value). */ iterator push_front(const value_type &value); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /** Equivalent to insert(begin(), value). */ + iterator push_front(value_type &&value); +#endif + /** Equivalent to insert(end(), value). */ iterator push_back(const value_type &value); + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES /** Equivalent to insert(end(), value). */ iterator push_back(value_type &&value); diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index d932dc59d8..a7bb458f9b 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -137,8 +137,8 @@ static void reset_counters() // return a; // } -// Test copy/move of the entire test_container -static void test_container() +// Test copy/move constructor of the entire test_container +static void test_constructor() { test_ptree a("value"); @@ -177,10 +177,34 @@ static void test_push_back() BOOST_CHECK(data_type::copy_assigments == 0); } +static void test_push_front() +{ + test_ptree tree; + + // push_back - copy + test_ptree::value_type child1("key1", test_ptree("c1")); + + reset_counters(); + tree.push_front(child1); + + BOOST_CHECK(data_type::copy_ctors == 1); + BOOST_CHECK(key_type::copy_ctors == 1); + + // push_back - move + test_ptree::value_type child2("key2", test_ptree("c2")); + + reset_counters(); + tree.push_front(std::move(child2)); + + BOOST_CHECK(data_type::copy_ctors == 0); + BOOST_CHECK(data_type::copy_assigments == 0); +} + int test_main(int, char *[]) { - test_container(); + test_constructor(); test_push_back(); + test_push_front(); return 0; } From fe85d70bda713896ff45125063fd33d56034a390 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 18:03:53 +0200 Subject: [PATCH 15/16] Added, tested moving insert --- .../detail/ptree_implementation.hpp | 9 +++++++ include/boost/property_tree/ptree.hpp | 8 +++++++ test/test_lifecycle.cpp | 24 +++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/boost/property_tree/detail/ptree_implementation.hpp b/include/boost/property_tree/detail/ptree_implementation.hpp index 185c1e9a0f..b959295d7b 100644 --- a/include/boost/property_tree/detail/ptree_implementation.hpp +++ b/include/boost/property_tree/detail/ptree_implementation.hpp @@ -348,6 +348,15 @@ namespace boost { namespace property_tree return iterator(subs::ch(this).insert(where.base(), value).first); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template inline + typename basic_ptree::iterator + basic_ptree::insert(iterator where, value_type &&value) + { + return iterator(subs::ch(this).insert(where.base(), std::move(value)).first); + } +#endif + template template inline void basic_ptree::insert(iterator where, It first, It last) diff --git a/include/boost/property_tree/ptree.hpp b/include/boost/property_tree/ptree.hpp index d10519e2af..e897fc8d12 100644 --- a/include/boost/property_tree/ptree.hpp +++ b/include/boost/property_tree/ptree.hpp @@ -135,6 +135,14 @@ namespace boost { namespace property_tree */ iterator insert(iterator where, const value_type &value); +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + /** Insert a copy of the given tree with its key just before the given + * position in this node. This operation invalidates no iterators. + * @return An iterator to the newly created child. + */ + iterator insert(iterator where, value_type &&value); +#endif + /** Range insert. Equivalent to: * @code * for(; first != last; ++first) insert(where, *first); diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index a7bb458f9b..bc1d28cfbc 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -200,11 +200,35 @@ static void test_push_front() BOOST_CHECK(data_type::copy_assigments == 0); } +static void test_insert() +{ + test_ptree tree; + + // push_back - copy + test_ptree::value_type child1("key1", test_ptree("c1")); + + reset_counters(); + tree.insert(tree.begin(), child1); + + BOOST_CHECK(data_type::copy_ctors == 1); + BOOST_CHECK(key_type::copy_ctors == 1); + + // push_back - move + test_ptree::value_type child2("key2", test_ptree("c2")); + + reset_counters(); + tree.insert(tree.begin(), std::move(child2)); + + BOOST_CHECK(data_type::copy_ctors == 0); + BOOST_CHECK(data_type::copy_assigments == 0); +} + int test_main(int, char *[]) { test_constructor(); test_push_back(); test_push_front(); + test_insert(); return 0; } From d6c0112c001591cb822523137e9712f1386bf776 Mon Sep 17 00:00:00 2001 From: Maciek Gajewski Date: Sun, 14 May 2017 18:07:02 +0200 Subject: [PATCH 16/16] Added test for assignment operators --- test/test_lifecycle.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/test/test_lifecycle.cpp b/test/test_lifecycle.cpp index bc1d28cfbc..eaa29e2bff 100644 --- a/test/test_lifecycle.cpp +++ b/test/test_lifecycle.cpp @@ -137,7 +137,6 @@ static void reset_counters() // return a; // } -// Test copy/move constructor of the entire test_container static void test_constructor() { test_ptree a("value"); @@ -154,6 +153,23 @@ static void test_constructor() BOOST_CHECK(data_type::copy_assigments == 0); } +static void test_assignment() +{ + test_ptree a("a"); + test_ptree b("a"); + + // Copy + reset_counters(); + b = a; + BOOST_CHECK(data_type::copy_ctors == 1); + + // Move + reset_counters(); + b = std::move(a); + BOOST_CHECK(data_type::copy_ctors == 0); + BOOST_CHECK(data_type::copy_assigments == 0); +} + static void test_push_back() { test_ptree tree; @@ -229,6 +245,7 @@ int test_main(int, char *[]) test_push_back(); test_push_front(); test_insert(); + test_assignment(); return 0; }