Update of /cvsroot/boost/boost/libs/property_tree/examples
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv27259/examples

Added Files:
        custom_data_type.cpp debug_settings.cpp debug_settings.xml 
        empty_ptree_trick.cpp info_grammar_spirit.cpp 
        settings_fully-existent.info settings_non-existent.info 
        settings_partially-existent.info speed_test.cpp 
Log Message:
Adding property_tree

--- NEW FILE: custom_data_type.cpp ---
// ----------------------------------------------------------------------------
// 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/property_tree/info_parser.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/any.hpp>
#include <list>
#include <string>
#include <iostream>

// Custom translator that works with boost::any instead of std::string
struct my_translator
{

    // Custom extractor - converts data from boost::any to T
    template<class Ptree, class T> 
    bool get_value(const Ptree &pt, T &value) const
    {
        value = boost::any_cast<T>(pt.data());
        return true;    // Success
    }

    // Custom inserter - converts data from T to boost::any
    template<class Ptree, class T> 
    bool put_value(Ptree &pt, const T &value) const
    {
        pt.data() = value;
        return true;
    }

};

int main()
{
    
    using namespace boost::property_tree;
    
    // Property_tree with boost::any as data type
    // Key comparison:  std::less<std::string>
    // Key type:        std::string
    // Path type:       path
    // Data type:       boost::any
    // Translator type: my_translator
    typedef basic_ptree<std::less<std::string>, std::string, path, boost::any, 
my_translator> my_ptree;
    my_ptree pt;

    // Put/get int value
    pt.put("int value", 3);
    int int_value = pt.get<int>("int value");
    std::cout << "Int value: " << int_value << "\n";

    // Put/get string value
    pt.put<std::string>("string value", "foo bar");
    std::string string_value = pt.get<std::string>("string value");
    std::cout << "String value: " << string_value << "\n";

    // Put/get list<int> value
    int list_data[] = { 1, 2, 3, 4, 5 };
    pt.put<std::list<int> >("list value", std::list<int>(list_data, list_data + 
sizeof(list_data) / sizeof(*list_data)));
    std::list<int> list_value = pt.get<std::list<int> >("list value");
    std::cout << "List value: ";
    for (std::list<int>::iterator it = list_value.begin(); it != 
list_value.end(); ++it)
        std::cout << *it << ' ';
    std::cout << '\n';
}

--- NEW FILE: debug_settings.cpp ---
// ----------------------------------------------------------------------------
// 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/xml_parser.hpp>
//#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
#include <iostream>

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);
};

void debug_settings::load(const std::string &filename)
{

    // Create empty property tree object
    using boost::property_tree::ptree;
    ptree pt;

    // Load XML file and put its contents in property tree. 
    // No namespace qualification is needed, because of Koenig 
    // lookup on the second argument. If reading fails, exception
    // is thrown.
    read_xml(filename, pt);

    // Get filename and store it in m_file variable. Note that 
    // we specify a path to the value using notation where keys 
    // are separated with dots (different separator may be used 
    // if keys themselves contain dots). If debug.filename key is 
    // not found, exception is thrown.
    m_file = pt.get<std::string>("debug.filename");
    
    // Get debug level and store it in m_level variable. This is 
    // another version of get method: if debug.level key is not 
    // found, it will return default value (specified by second 
    // parameter) instead of throwing. Type of the value extracted 
    // is determined by type of second parameter, so we can simply 
    // write get(...) instead of get<int>(...).
    m_level = pt.get("debug.level", 0);

    // Iterate over debug.modules section and store all found 
    // modules in m_modules set. get_child() function returns a 
    // reference to child at specified path; if there is no such 
    // child, it throws. Property tree iterator can be used in 
    // the same way as standard container iterator. Category 
    // is bidirectional_iterator.
    //BOOST_FOREACH(ptree::value_type &v, pt.get_child("debug.modules"))
    //    m_modules.insert(v.second.data());

}

void debug_settings::save(const std::string &filename)
{

    // Create empty property tree object
    using boost::property_tree::ptree;
    ptree pt;

    // Put log filename in property tree
    pt.put("debug.filename", m_file);

    // 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
    // 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 
    // and put_value functions
    //BOOST_FOREACH(const std::string &name, m_modules)
    //    pt.put("debug.modules.module", name, true);
    
    // Write property tree to XML file
    write_xml(filename, pt);

}

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;
}

--- NEW FILE: debug_settings.xml ---
<?xml version="1.0" encoding="utf-8"?>
<debug>
    <filename>debug.log</filename>
    <modules>
        <module>Finance</module>
        <module>Admin</module>
        <module>HR</module>
    </modules>
    <level>2</level>
</debug>

--- NEW FILE: empty_ptree_trick.cpp ---
// ----------------------------------------------------------------------------
// 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;
}

--- NEW FILE: info_grammar_spirit.cpp ---
// ----------------------------------------------------------------------------
// 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);

}

--- NEW FILE: settings_fully-existent.info ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: settings_non-existent.info ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: settings_partially-existent.info ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: speed_test.cpp ---
// ----------------------------------------------------------------------------
// 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], 
empty_ptree<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);

}


-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Boost-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/boost-cvs

Reply via email to