diff --git a/doc/property_tree.qbk b/doc/property_tree.qbk index 0fadf51..61e33b6 100644 --- a/doc/property_tree.qbk +++ b/doc/property_tree.qbk @@ -53,6 +53,7 @@ [def __ptree_get_value_optional__ [memberref boost::property_tree::basic_ptree::get_value_optional get_value_optional]] [def __ptree_get_child__ [memberref boost::property_tree::basic_ptree::get_child get_child]] [def __ptree_put__ [memberref boost::property_tree::basic_ptree::put put]] +[def __ptree_put__ [memberref boost::property_tree::basic_ptree::add add]] [def __ptree_put_value__ [memberref boost::property_tree::basic_ptree::put_value put_value]] [/ free-functions] @@ -104,10 +105,6 @@ these three basic patterns of usage: itself.] Used when you want to vary control flow depending on get success/failure. Or to check for presence of a key. -# [*Why does the separator character come before the path and not after - as one would expect?] -It helps with overload resolution in some cases. - [heading Future Development] * More parsers: YAML, environment strings. * More robust XML parser. diff --git a/doc/tutorial.qbk b/doc/tutorial.qbk index a35b8ca..4d374c3 100644 --- a/doc/tutorial.qbk +++ b/doc/tutorial.qbk @@ -106,7 +106,7 @@ Now the save() function. It is also 7 lines of code: // be achieved using a combination of the insert and put_own // functions. BOOST_FOREACH(const std::string &name, m_modules) - pt.__ptree_put__("debug.modules.module", name, true); + pt.__ptree_add__("debug.modules.module", name); // Write the property tree to the XML file. __write_xml__(filename, pt); diff --git a/examples/custom_data_type.cpp b/examples/custom_data_type.cpp index 86097e9..dbc905f 100644 --- a/examples/custom_data_type.cpp +++ b/examples/custom_data_type.cpp @@ -14,35 +14,28 @@ // container (instead of std::string that standard ptree has). #include -#include -#include -#include -#include #include #include #include #include // Custom translator that works with boost::any instead of std::string -struct my_translator +template +struct variant_translator { + typedef Ext external_type; + typedef Int internal_type; - // Custom extractor - converts data from boost::any to T - template - bool get_value(const Ptree &pt, T &value) const + external_type + get_value(const internal_type &value) const { - value = boost::any_cast(pt.data()); - return true; // Success + return boost::any_cast(value); } - - // Custom inserter - converts data from T to boost::any - template - bool put_value(Ptree &pt, const T &value) const + internal_type + put_value(const external_type &value) const { - pt.data() = value; - return true; + return value; } - }; int main() @@ -51,30 +44,45 @@ int main() using namespace boost::property_tree; // Property_tree with boost::any as data type - // Key comparison: std::less // Key type: std::string - // Path type: path // Data type: boost::any - // Translator type: my_translator - typedef basic_ptree, std::string, path, boost::any, my_translator> my_ptree; + // Key comparison: default (std::less) + typedef basic_ptree my_ptree; my_ptree pt; // Put/get int value - pt.put("int value", 3); - int int_value = pt.get("int value"); + typedef variant_translator int_tran; + pt.put("int value", 3, int_tran()); + int int_value = pt.get("int value", int_tran()); std::cout << "Int value: " << int_value << "\n"; // Put/get string value - pt.put("string value", "foo bar"); - std::string string_value = pt.get("string value"); + typedef variant_translator string_tran; + pt.put("string value", "foo bar", string_tran()); + std::string string_value = pt.get( + "string value" + , string_tran() + ); std::cout << "String value: " << string_value << "\n"; // Put/get list value + typedef std::list intlist; + typedef variant_translator intlist_tran; int list_data[] = { 1, 2, 3, 4, 5 }; - pt.put >("list value", std::list(list_data, list_data + sizeof(list_data) / sizeof(*list_data))); - std::list list_value = pt.get >("list value"); + pt.put( + "list value" + , intlist( + list_data + , list_data + sizeof(list_data) / sizeof(*list_data) + ) + , intlist_tran() + ); + intlist list_value = pt.get( + "list value" + , intlist_tran() + ); std::cout << "List value: "; - for (std::list::iterator it = list_value.begin(); it != list_value.end(); ++it) + for (intlist::iterator it = list_value.begin(); it != list_value.end(); ++it) std::cout << *it << ' '; std::cout << '\n'; } diff --git a/examples/debug_settings.cpp b/examples/debug_settings.cpp index f7bcef7..78d704a 100644 --- a/examples/debug_settings.cpp +++ b/examples/debug_settings.cpp @@ -10,7 +10,7 @@ #include #include -//#include +#include #include #include #include @@ -77,15 +77,15 @@ void debug_settings::save(const std::string &filename) // Put debug level in property tree pt.put("debug.level", m_level); - // Iterate over modules in set and put them in property - // tree. Note that put function places new key at the + // Iterate over modules in set and put them in property + // tree. Note that the add function places new key at the // end of list of keys. This is fine in most of the // situations. If you want to place item at some other // place (i.e. at front or somewhere in the middle), - // this can be achieved using combination of insert + // this can be achieved using a combination of the insert // and put_value functions - //BOOST_FOREACH(const std::string &name, m_modules) - // pt.put("debug.modules.module", name, true); + BOOST_FOREACH(const std::string &name, m_modules) + pt.add("debug.modules.module", name); // Write property tree to XML file write_xml(filename, pt); diff --git a/test/test_json_parser.cpp b/test/test_json_parser.cpp index 4d37a93..d4d8f47 100644 --- a/test/test_json_parser.cpp +++ b/test/test_json_parser.cpp @@ -235,7 +235,7 @@ const char *ok_data_11 = "}\n"; const char *ok_data_12 = - "{\" \\\" \\\\ \\0 \\b \\f \\n \\r \\t \" : \"multi\" \"-\" \"string\"}"; + "{\" \\\" \\\\ \\b \\f \\n \\r \\t \" : \"multi\" \"-\" \"string\"}"; const char *error_data_1 = ""; // No root object @@ -342,7 +342,7 @@ void test_json_parser() generic_parser_test_ok ( ReadFunc(), WriteFunc(), ok_data_12, NULL, - "testok12.json", NULL, "testok12out.json", 2, 12, 19 + "testok12.json", NULL, "testok12out.json", 2, 12, 17 ); generic_parser_test_error diff --git a/test/test_property_tree.cpp b/test/test_property_tree.cpp index 9634091..aed4827 100644 --- a/test/test_property_tree.cpp +++ b/test/test_property_tree.cpp @@ -9,8 +9,10 @@ // ---------------------------------------------------------------------------- #include "test_utils.hpp" #include +#include #include #include +#include // If using VC, disable some warnings that trip in boost::serialization bowels #ifdef BOOST_MSVC @@ -152,6 +154,7 @@ int test_main(int, char *[]) test_front_back(pt); test_get_put(pt); test_get_child_put_child(pt); + test_equal_range(pt); test_path_separator(pt); test_path(pt); test_precision(pt); @@ -184,6 +187,7 @@ int test_main(int, char *[]) test_front_back(pt); test_get_put(pt); test_get_child_put_child(pt); + test_equal_range(pt); test_path_separator(pt); test_path(pt); test_precision(pt); @@ -216,6 +220,7 @@ int test_main(int, char *[]) test_front_back(pt); test_get_put(pt); test_get_child_put_child(pt); + test_equal_range(pt); test_path_separator(pt); test_path(pt); test_precision(pt); @@ -248,6 +253,7 @@ int test_main(int, char *[]) test_front_back(pt); test_get_put(pt); test_get_child_put_child(pt); + test_equal_range(pt); test_path_separator(pt); test_path(pt); test_precision(pt); diff --git a/test/test_property_tree.hpp b/test/test_property_tree.hpp index 8b8d33d..4e670b1 100644 --- a/test/test_property_tree.hpp +++ b/test/test_property_tree.hpp @@ -914,6 +914,21 @@ void test_get_child_put_child(PTREE *) } +void test_equal_range(PTREE *) +{ + PTREE pt; + pt.add_child(T("k1"), PTREE()); + pt.add_child(T("k2"), PTREE()); + pt.add_child(T("k1"), PTREE()); + pt.add_child(T("k3"), PTREE()); + pt.add_child(T("k1"), PTREE()); + pt.add_child(T("k2"), PTREE()); + + BOOST_CHECK(boost::distance(pt.equal_range(T("k1"))) == 3); + BOOST_CHECK(boost::distance(pt.equal_range(T("k2"))) == 2); + BOOST_CHECK(boost::distance(pt.equal_range(T("k3"))) == 1); +} + void test_path_separator(PTREE *) { diff --git a/test/test_xml_parser_common.hpp b/test/test_xml_parser_common.hpp index 4c51111..6e6a124 100644 --- a/test/test_xml_parser_common.hpp +++ b/test/test_xml_parser_common.hpp @@ -19,7 +19,8 @@ struct ReadFuncWS template void operator()(const std::string &filename, Ptree &pt) const { - boost::property_tree::read_xml(filename, pt); + boost::property_tree::read_xml(filename, pt, + boost::property_tree::xml_parser::no_concat_text); } }; @@ -72,7 +73,7 @@ void test_xml_parser() generic_parser_test_ok ( ReadFuncWS(), WriteFuncWS(), ok_data_2, NULL, - "testok2a.xml", NULL, "testok2aout.xml", 6, 18, 8 + "testok2a.xml", NULL, "testok2aout.xml", 15, 23, 89 ); generic_parser_test_ok @@ -84,7 +85,7 @@ void test_xml_parser() generic_parser_test_ok ( ReadFuncWS(), WriteFuncWS(), ok_data_3, NULL, - "testok3a.xml", NULL, "testok3aout.xml", 787, 32523, 3831 + "testok3a.xml", NULL, "testok3aout.xml", 1662, 35377, 11706 ); generic_parser_test_ok @@ -96,14 +97,14 @@ void test_xml_parser() generic_parser_test_ok ( ReadFuncWS(), WriteFuncWS(), ok_data_4, NULL, - "testok4.xml", NULL, "testok4out.xml", 5, 2, 20 + "testok4.xml", NULL, "testok4out.xml", 11, 7, 74 ); generic_parser_test_ok ( ReadFuncWS(), WriteFuncWS(), ok_data_5, NULL, "testok5.xml", NULL, "testok5out.xml", - 2, umlautsize(), 3 + 3, umlautsize(), 12 ); generic_parser_test_error @@ -118,6 +119,12 @@ void test_xml_parser() "testerr2.xml", NULL, "testerr2out.xml", 2 ); + generic_parser_test_ok + ( + ReadFuncWS(), WriteFuncWS(), bug_data_pr2855, NULL, + "testpr2855.xml", NULL, "testpr2855out.xml", 3, 7, 14 + ); + } #endif diff --git a/test/test_xml_parser_rapidxml.cpp b/test/test_xml_parser_rapidxml.cpp index 7aacfad..5a0e3d4 100644 --- a/test/test_xml_parser_rapidxml.cpp +++ b/test/test_xml_parser_rapidxml.cpp @@ -1,5 +1,6 @@ // ---------------------------------------------------------------------------- // Copyright (C) 2002-2006 Marcin Kalicinski +// Copyright (C) 2009-2010 Sebastian Redl // // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -19,10 +20,10 @@ int test_main(int argc, char *argv[]) { using namespace boost::property_tree; - using std::locale; test_xml_parser(); test_xml_parser(); #ifndef BOOST_NO_CWCHAR + using std::locale; // We need a UTF-8-aware global locale now. locale loc(locale(), new utf8_codecvt_facet); locale::global(loc); diff --git a/test/xml_parser_test_data.hpp b/test/xml_parser_test_data.hpp index a1f1637..c470816 100644 --- a/test/xml_parser_test_data.hpp +++ b/test/xml_parser_test_data.hpp @@ -760,4 +760,8 @@ const char *error_data_2 = "\n" ""; // XML tag not closed +const char *bug_data_pr2855 = + "\n" + " notrim"; + #endif