diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 18:24:20 +0000 |
commit | 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch) | |
tree | e5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/property_tree/examples | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/property_tree/examples')
10 files changed, 581 insertions, 0 deletions
diff --git a/src/boost/libs/property_tree/examples/Jamfile.v2 b/src/boost/libs/property_tree/examples/Jamfile.v2 new file mode 100644 index 00000000..07c382ae --- /dev/null +++ b/src/boost/libs/property_tree/examples/Jamfile.v2 @@ -0,0 +1,12 @@ +# Boost PropertyTree Library Example Jamfile +# Copyright (c) 2013 Sebastian Redl +# Distributed under the Boost Software License, Version 1.0. +# See http://www.boost.org/LICENSE_1_0.txt + +project + : requirements + <include>../../../ + : + ; + +exe debug_settings : debug_settings.cpp ; diff --git a/src/boost/libs/property_tree/examples/custom_data_type.cpp b/src/boost/libs/property_tree/examples/custom_data_type.cpp new file mode 100644 index 00000000..dbc905fe --- /dev/null +++ b/src/boost/libs/property_tree/examples/custom_data_type.cpp @@ -0,0 +1,88 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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 +// ---------------------------------------------------------------------------- + +// This example shows what need to be done to customize data_type of ptree. +// +// It creates my_ptree type, which is a basic_ptree having boost::any as its data +// container (instead of std::string that standard ptree has). + +#include <boost/property_tree/ptree.hpp> +#include <boost/any.hpp> +#include <list> +#include <string> +#include <iostream> + +// Custom translator that works with boost::any instead of std::string +template <class Ext, class Int = boost::any> +struct variant_translator +{ + typedef Ext external_type; + typedef Int internal_type; + + external_type + get_value(const internal_type &value) const + { + return boost::any_cast<external_type>(value); + } + internal_type + put_value(const external_type &value) const + { + return value; + } +}; + +int main() +{ + + using namespace boost::property_tree; + + // Property_tree with boost::any as data type + // Key type: std::string + // Data type: boost::any + // Key comparison: default (std::less<std::string>) + typedef basic_ptree<std::string, boost::any> my_ptree; + my_ptree pt; + + // Put/get int value + typedef variant_translator<int> int_tran; + pt.put("int value", 3, int_tran()); + int int_value = pt.get<int>("int value", int_tran()); + std::cout << "Int value: " << int_value << "\n"; + + // Put/get string value + typedef variant_translator<std::string> string_tran; + pt.put<std::string>("string value", "foo bar", string_tran()); + std::string string_value = pt.get<std::string>( + "string value" + , string_tran() + ); + std::cout << "String value: " << string_value << "\n"; + + // Put/get list<int> value + typedef std::list<int> intlist; + typedef variant_translator<intlist> intlist_tran; + int list_data[] = { 1, 2, 3, 4, 5 }; + pt.put<intlist>( + "list value" + , intlist( + list_data + , list_data + sizeof(list_data) / sizeof(*list_data) + ) + , intlist_tran() + ); + intlist list_value = pt.get<intlist>( + "list value" + , intlist_tran() + ); + std::cout << "List value: "; + for (intlist::iterator it = list_value.begin(); it != list_value.end(); ++it) + std::cout << *it << ' '; + std::cout << '\n'; +} diff --git a/src/boost/libs/property_tree/examples/debug_settings.cpp b/src/boost/libs/property_tree/examples/debug_settings.cpp new file mode 100644 index 00000000..5e214290 --- /dev/null +++ b/src/boost/libs/property_tree/examples/debug_settings.cpp @@ -0,0 +1,95 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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 +// ---------------------------------------------------------------------------- + +//[debug_settings_includes +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> +#include <boost/foreach.hpp> +#include <string> +#include <set> +#include <exception> +#include <iostream> +namespace pt = boost::property_tree; +//] +//[debug_settings_data +struct debug_settings +{ + std::string m_file; // log filename + int m_level; // debug level + std::set<std::string> m_modules; // modules where logging is enabled + void load(const std::string &filename); + void save(const std::string &filename); +}; +//] +//[debug_settings_load +void debug_settings::load(const std::string &filename) +{ + // Create empty property tree object + pt::ptree tree; + + // Parse the XML into the property tree. + pt::read_xml(filename, tree); + + // Use the throwing version of get to find the debug filename. + // If the path cannot be resolved, an exception is thrown. + m_file = tree.get<std::string>("debug.filename"); + + // Use the default-value version of get to find the debug level. + // Note that the default value is used to deduce the target type. + m_level = tree.get("debug.level", 0); + + // Use get_child to find the node containing the modules, and iterate over + // its children. If the path cannot be resolved, get_child throws. + // A C++11 for-range loop would also work. + BOOST_FOREACH(pt::ptree::value_type &v, tree.get_child("debug.modules")) { + // The data function is used to access the data stored in a node. + m_modules.insert(v.second.data()); + } + +} +//] +//[debug_settings_save +void debug_settings::save(const std::string &filename) +{ + // Create an empty property tree object. + pt::ptree tree; + + // Put the simple values into the tree. The integer is automatically + // converted to a string. Note that the "debug" node is automatically + // created if it doesn't exist. + tree.put("debug.filename", m_file); + tree.put("debug.level", m_level); + + // Add all the modules. Unlike put, which overwrites existing nodes, add + // adds a new node at the lowest level, so the "modules" node will have + // multiple "module" children. + BOOST_FOREACH(const std::string &name, m_modules) + tree.add("debug.modules.module", name); + + // Write property tree to XML file + pt::write_xml(filename, tree); +} +//] + +int main() +{ + try + { + debug_settings ds; + ds.load("debug_settings.xml"); + ds.save("debug_settings_out.xml"); + std::cout << "Success\n"; + } + catch (std::exception &e) + { + std::cout << "Error: " << e.what() << "\n"; + } + return 0; +} diff --git a/src/boost/libs/property_tree/examples/debug_settings.xml b/src/boost/libs/property_tree/examples/debug_settings.xml new file mode 100644 index 00000000..2ac170ec --- /dev/null +++ b/src/boost/libs/property_tree/examples/debug_settings.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +Copyright (C) 2006 Marcin Kalicinski +Distributed under the Boost Software License, Version 1.0. +See http://www.boost.org/LICENSE_1_0.txt +--> +<debug> + <filename>debug.log</filename> + <modules> + <module>Finance</module> + <module>Admin</module> + <module>HR</module> + </modules> + <level>2</level> +</debug> diff --git a/src/boost/libs/property_tree/examples/empty_ptree_trick.cpp b/src/boost/libs/property_tree/examples/empty_ptree_trick.cpp new file mode 100644 index 00000000..37285b24 --- /dev/null +++ b/src/boost/libs/property_tree/examples/empty_ptree_trick.cpp @@ -0,0 +1,71 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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 +// ---------------------------------------------------------------------------- + +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/info_parser.hpp> +#include <iostream> +#include <iomanip> +#include <string> + +using namespace boost::property_tree; + +// Process settings using empty ptree trick. Note that it is considerably simpler +// than version which does not use the "trick" +void process_settings(const std::string &filename) +{ + ptree pt; + read_info(filename, pt); + const ptree &settings = pt.get_child("settings", empty_ptree<ptree>()); + std::cout << "\n Processing " << filename << std::endl; + std::cout << " Setting 1 is " << settings.get("setting1", 0) << std::endl; + std::cout << " Setting 2 is " << settings.get("setting2", 0.0) << std::endl; + std::cout << " Setting 3 is " << settings.get("setting3", "default") << std::endl; +} + +// Process settings not using empty ptree trick. This one must duplicate much of the code. +void process_settings_without_trick(const std::string &filename) +{ + ptree pt; + read_info(filename, pt); + if (boost::optional<ptree &> settings = pt.get_child_optional("settings")) + { + std::cout << "\n Processing " << filename << std::endl; + std::cout << " Setting 1 is " << settings.get().get("setting1", 0) << std::endl; + std::cout << " Setting 2 is " << settings.get().get("setting2", 0.0) << std::endl; + std::cout << " Setting 3 is " << settings.get().get("setting3", "default") << std::endl; + } + else + { + std::cout << "\n Processing " << filename << std::endl; + std::cout << " Setting 1 is " << 0 << std::endl; + std::cout << " Setting 2 is " << 0.0 << std::endl; + std::cout << " Setting 3 is " << "default" << std::endl; + } +} + +int main() +{ + try + { + std::cout << "Processing settings with empty-ptree-trick:\n"; + process_settings("settings_fully-existent.info"); + process_settings("settings_partially-existent.info"); + process_settings("settings_non-existent.info"); + std::cout << "\nProcessing settings without empty-ptree-trick:\n"; + process_settings_without_trick("settings_fully-existent.info"); + process_settings_without_trick("settings_partially-existent.info"); + process_settings_without_trick("settings_non-existent.info"); + } + catch (std::exception &e) + { + std::cout << "Error: " << e.what() << "\n"; + } + return 0; +} diff --git a/src/boost/libs/property_tree/examples/info_grammar_spirit.cpp b/src/boost/libs/property_tree/examples/info_grammar_spirit.cpp new file mode 100644 index 00000000..07025341 --- /dev/null +++ b/src/boost/libs/property_tree/examples/info_grammar_spirit.cpp @@ -0,0 +1,152 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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 +// ---------------------------------------------------------------------------- + +/* This is grammar of INFO file format written in form of boost::spirit rules. + For simplicity, it does not parse #include directive. Note that INFO parser + included in property_tree library does not use Spirit. +*/ + +//#define BOOST_SPIRIT_DEBUG // uncomment to enable debug output +#include <boost/spirit.hpp> + +struct info_grammar: public boost::spirit::grammar<info_grammar> +{ + + template<class Scanner> + struct definition + { + + boost::spirit::rule<typename boost::spirit::lexeme_scanner<Scanner>::type> chr, qchr, escape_seq; + boost::spirit::rule<Scanner> string, qstring, cstring, key, value, entry, info; + + definition(const info_grammar &self) + { + + using namespace boost::spirit; + + escape_seq = chset_p("0abfnrtv\"\'\\"); + chr = (anychar_p - space_p - '\\' - '{' - '}' - '#' - '"') | ('\\' >> escape_seq); + qchr = (anychar_p - '"' - '\n' - '\\') | ('\\' >> escape_seq); + string = lexeme_d[+chr]; + qstring = lexeme_d['"' >> *qchr >> '"']; + cstring = lexeme_d['"' >> *qchr >> '"' >> '\\']; + key = string | qstring; + value = string | qstring | (+cstring >> qstring) | eps_p; + entry = key >> value >> !('{' >> *entry >> '}'); + info = *entry >> end_p; + + // Debug nodes + BOOST_SPIRIT_DEBUG_NODE(escape_seq); + BOOST_SPIRIT_DEBUG_NODE(chr); + BOOST_SPIRIT_DEBUG_NODE(qchr); + BOOST_SPIRIT_DEBUG_NODE(string); + BOOST_SPIRIT_DEBUG_NODE(qstring); + BOOST_SPIRIT_DEBUG_NODE(key); + BOOST_SPIRIT_DEBUG_NODE(value); + BOOST_SPIRIT_DEBUG_NODE(entry); + BOOST_SPIRIT_DEBUG_NODE(info); + + } + + const boost::spirit::rule<Scanner> &start() const + { + return info; + } + + }; +}; + +void info_parse(const char *s) +{ + + using namespace boost::spirit; + + // Parse and display result + info_grammar g; + parse_info<const char *> pi = parse(s, g, space_p | comment_p(";")); + std::cout << "Parse result: " << (pi.hit ? "Success" : "Failure") << "\n"; + +} + +int main() +{ + + // Sample data 1 + const char *data1 = + "\n" + "key1 data1\n" + "{\n" + "\tkey data\n" + "}\n" + "key2 \"data2 \" {\n" + "\tkey data\n" + "}\n" + "key3 \"data\"\n" + "\t \"3\" {\n" + "\tkey data\n" + "}\n" + "\n" + "\"key4\" data4\n" + "{\n" + "\tkey data\n" + "}\n" + "\"key.5\" \"data.5\" { \n" + "\tkey data \n" + "}\n" + "\"key6\" \"data\"\n" + "\t \"6\" {\n" + "\tkey data\n" + "}\n" + " \n" + "key1 data1\n" + "{\n" + "\tkey data\n" + "}\n" + "key2 \"data2 \" {\n" + "\tkey data\n" + "}\n" + "key3 \"data\"\n" + "\t \"3\" {\n" + "\tkey data\n" + "}\n" + "\n" + "\"key4\" data4\n" + "{\n" + "\tkey data\n" + "}\n" + "\"key.5\" \"data.5\" {\n" + "\tkey data\n" + "}\n" + "\"key6\" \"data\"\n" + "\t \"6\" {\n" + "\tkey data\n" + "}\n" + "\\\\key\\t7 data7\\n\\\"data7\\\"\n" + "{\n" + "\tkey data\n" + "}\n" + "\"\\\\key\\t8\" \"data8\\n\\\"data8\\\"\"\n" + "{\n" + "\tkey data\n" + "}\n" + "\n"; + + // Sample data 2 + const char *data2 = + "key1\n" + "key2\n" + "key3\n" + "key4\n"; + + // Parse sample data + info_parse(data1); + info_parse(data2); + +} diff --git a/src/boost/libs/property_tree/examples/settings_fully-existent.info b/src/boost/libs/property_tree/examples/settings_fully-existent.info new file mode 100644 index 00000000..bec7a64b --- /dev/null +++ b/src/boost/libs/property_tree/examples/settings_fully-existent.info @@ -0,0 +1,6 @@ +settings +{ + setting1 15 + setting2 9.876 + setting3 Alice in Wonderland +} diff --git a/src/boost/libs/property_tree/examples/settings_non-existent.info b/src/boost/libs/property_tree/examples/settings_non-existent.info new file mode 100644 index 00000000..4f76b2a4 --- /dev/null +++ b/src/boost/libs/property_tree/examples/settings_non-existent.info @@ -0,0 +1,6 @@ +;settings // non-existent +;{ +; setting1 15 +; setting2 9.876 +; setting3 Alice in Wonderland +;} diff --git a/src/boost/libs/property_tree/examples/settings_partially-existent.info b/src/boost/libs/property_tree/examples/settings_partially-existent.info new file mode 100644 index 00000000..ed5e8c22 --- /dev/null +++ b/src/boost/libs/property_tree/examples/settings_partially-existent.info @@ -0,0 +1,6 @@ +settings +{ + setting1 15 + ;setting2 9.876 // non-existent + ;setting3 Alice in Wonderland // non-existent +} diff --git a/src/boost/libs/property_tree/examples/speed_test.cpp b/src/boost/libs/property_tree/examples/speed_test.cpp new file mode 100644 index 00000000..4d5efd8c --- /dev/null +++ b/src/boost/libs/property_tree/examples/speed_test.cpp @@ -0,0 +1,130 @@ +// ---------------------------------------------------------------------------- +// Copyright (C) 2002-2006 Marcin Kalicinski +// +// 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 +// ---------------------------------------------------------------------------- + +#define _HAS_ITERATOR_DEBUGGING 0 + +#include <boost/property_tree/ptree.hpp> +#include <boost/format.hpp> +#include <boost/shared_array.hpp> +#include <iostream> +#include <ctime> +#include <algorithm> + +using namespace std; +using namespace boost; +using namespace boost::property_tree; + +string dummy; +vector<string> keys; +vector<string> shuffled_keys; + +void prepare_keys(int size) +{ + // Prepare keys + keys.clear(); + for (int i = 0; i < size; ++i) + keys.push_back((format("%d") % i).str()); + shuffled_keys = keys; + srand(0); + random_shuffle(shuffled_keys.begin(), shuffled_keys.end()); +} + +void clock_push_back(int size) +{ + prepare_keys(size); + int max_repeats = 1000000 / size; + shared_array<ptree> pt_array(new ptree[max_repeats]); + + int n = 0; + clock_t t1 = clock(), t2; + do + { + if (n >= max_repeats) + break; + ptree &pt = pt_array[n]; + for (int i = 0; i < size; ++i) + pt.push_back(ptree::value_type(shuffled_keys[i], ptree())); + t2 = clock(); + ++n; + } while (t2 - t1 < CLOCKS_PER_SEC); + + cout << " push_back (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; + +} + +void clock_find(int size) +{ + prepare_keys(size); + + ptree pt; + for (int i = 0; i < size; ++i) + pt.push_back(ptree::value_type(keys[i], ptree("data"))); + + int n = 0; + clock_t t1 = clock(), t2; + do + { + for (int i = 0; i < size; ++i) + pt.find(shuffled_keys[i]); + t2 = clock(); + ++n; + } while (t2 - t1 < CLOCKS_PER_SEC); + + cout << " find (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; + +} + +void clock_erase(int size) +{ + prepare_keys(size); + + int max_repeats = 100000 / size; + shared_array<ptree> pt_array(new ptree[max_repeats]); + + ptree pt; + for (int n = 0; n < max_repeats; ++n) + for (int i = 0; i < size; ++i) + pt_array[n].push_back(ptree::value_type(keys[i], ptree("data"))); + + int n = 0; + clock_t t1 = clock(), t2; + do + { + if (n >= max_repeats) + break; + ptree &pt = pt_array[n]; + for (int i = 0; i < size; ++i) + pt.erase(shuffled_keys[i]); + t2 = clock(); + ++n; + } while (t2 - t1 < CLOCKS_PER_SEC); + + cout << " erase (" << size << "): " << double(t2 - t1) / CLOCKS_PER_SEC / n * 1000 << " ms\n"; +} + +int main() +{ + + // push_back + clock_push_back(10); + clock_push_back(100); + clock_push_back(1000); + + // erase + clock_erase(10); + clock_erase(100); + clock_erase(1000); + + // find + clock_find(10); + clock_find(100); + clock_find(1000); + +} |