與ajson庫用法類似
Example:
struct examle_struct
{
int _property_int;
std::string _property_str;
std::string value_str;
bool value_bool;
int value_int;
std::vector<int> value_vec;
}
AXML(examle_struct, (_property_int)(_property_str)(value_str)(value_bool)(value_int)(value_vec))
int main()
{
//to xml
std::istringstream iss;
examle_struct exam;
exam._property_int = 1;
exam._property_str = "hello";
exam.value_str = "world";
exam.value_bool = false;
exam.value_int = 10;
exam.value_vec << 1 << 2 << 3;
boost::axml::save(exam, "examle_struct", iss);
std::cout << iss.str() << std::endl;
//from xml
std::string xml_str = iss.str();
std::ostringstream oss(xml_str);
examle_struct exam1;
boost::axml::load(exam1,oss);
return 0;
}
XML解析 Src:
#pragma once
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <iostream>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/property_tree/detail/rapidxml.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/exception/diagnostic_information.hpp>
namespace boost
{
namespace axml
{
using namespace boost::property_tree::detail::rapidxml;
template <typename ty>
struct node_support_read_impl
{
typedef ty value_type;
typedef node_support_read_impl<ty> impl;
static void read(xml_node<char>& xml_value, value_type& value) {}
};
template <typename ty>
struct attribute_support_read_impl
{
typedef ty value_type;
typedef attribute_support_read_impl<ty> impl;
static void read(xml_attribute<char>& xml_value, value_type& value) {}
};
template <typename ty>
struct node_support_write_impl
{
typedef ty value_type;
typedef node_support_write_impl<ty> impl;
static void write(std::ostream& stream, std::string name, const value_type& value) {}
};
template <typename ty>
struct attribute_support_write_impl
{
typedef ty value_type;
typedef attribute_support_write_impl<ty> impl;
static void write(std::ostream& stream, std::string name, const value_type& value) {}
};
// template <typename ty>
// struct node_support_read;
//
// template <typename ty>
// struct attribute_support_read;
//
// template <typename ty>
// struct value_support_write;
//
// template <typename ty>
// struct attribute_support_write;
template<typename ty>
struct integer_arithmetic_support_read_impl
{
typedef ty value_type;
static void read(xml_base<char>& xml_value, value_type& value)
{
std::string str_value(xml_value.value());
if (str_value.empty())
{
value = 0;
return;
}
value = boost::lexical_cast<value_type>(str_value);
}
};
template<typename ty>
struct integer_arithmetic_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string name, const value_type& value)
{
std::string buffer = boost::str(boost::format("%1%") % value);
if (name[0] == '_')
{
std::string attr_name = name.substr(1);
stream << boost::str(boost::format(" %s=%s") % attr_name %buffer);
}
else
{
stream << boost::str(boost::format("\n<%s>%s</%s>") % name %buffer %name);
}
}
};
template<typename ty>
struct float_arithmetic_support_read_impl
{
typedef ty value_type;
static void read(xml_base<char>& xml_value, value_type& value)
{
std::string str_value(xml_value.value());
if (str_value.empty())
{
value = 0.0;
return;
}
value = boost::lexical_cast<value_type>(str_value);
}
};
template<typename ty>
struct float_arithmetic_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string name, const value_type& value)
{
std::string str_value = boost::str(boost::format("%1%") % value);
if (name[0] == '_')
{
std::string attr_name = name.substr(1);
stream << boost::str(boost::format(" %s=%s") % attr_name %str_value);
}
else
{
stream << boost::str(boost::format("\n<%s>%s</%s>") % name %str_value %name);
}
}
};
template<>
struct integer_arithmetic_support_read_impl <bool>
{
typedef bool value_type;
static void read(xml_base<char>& xml_value, value_type& value)
{
std::string str_value(xml_value.value());
if (str_value.empty())
{
value = 0;
return;
}
if (str_value == "0" || str_value == "false")
{
value = 0;
return;
}
value = 1;
}
};
template<>
struct integer_arithmetic_support_write_impl < bool >
{
typedef bool value_type;
static void write(std::ostream& stream, std::string name, const value_type& value)
{
std::string str_value = (value ? "1" : "0");
if (name[0] == '_')
{
std::string attr_name = name.substr(1);
stream << boost::str(boost::format(" %s=%s") % attr_name %str_value);
}
else
{
stream << boost::str(boost::format("\n<%s>%s</%s>") % name %str_value %name);
}
}
};
template <typename ty>
struct arithmetic_support_read_impl
{
typedef ty value_type;
typedef typename ::boost::mpl::if_<
::boost::is_integral<value_type>,
integer_arithmetic_support_read_impl<value_type>,
float_arithmetic_support_read_impl<value_type>
>::type impl;
};
template <typename ty>
struct arithmetic_support_write_impl
{
typedef ty value_type;
typedef typename ::boost::mpl::if_<
::boost::is_integral<value_type>,
integer_arithmetic_support_write_impl<value_type>,
float_arithmetic_support_write_impl<value_type>
>::type impl;
};
template<typename ty>
struct string_support_read_impl
{
typedef ty value_type;
static void read(xml_base<char>& xml_value, value_type& value)
{
std::string str_value(xml_value.value());
if (str_value.empty())
{
value = "";
return;
}
value = str_value;
}
};
template<typename ty>
struct string_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string name, const value_type& value)
{
std::string str_value(value);
if (name[0] == '_')
{
std::string attr_name = name.substr(1);
stream << boost::str(boost::format(" %s=\"%s\"") % attr_name %str_value);
}
else
{
stream << boost::str(boost::format("\n<%s>%s</%s>") % name %str_value %name);
}
}
};
template<typename char_traits_ty, typename char_alloc_type>
struct node_support_read_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type>>
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_read_impl<value_type> impl;
};
template<typename char_traits_ty, typename char_alloc_type>
struct attribute_support_read_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type>>
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_read_impl<value_type> impl;
};
template<typename char_traits_ty, typename char_alloc_type>
struct node_support_write_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type>>
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_write_impl<value_type> impl;
};
template<typename char_traits_ty, typename char_alloc_type>
struct attribute_support_write_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type>>
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_write_impl<value_type> impl;
};
template<int N>
struct char_array_support_read_impl
{
//typedef ty value_type;
static void read(xml_node<char>& xml_value, char(&value)[N])
{
char * nv = xml_value.value();
size_t nc = xml_value.value_size();
size_t vc = N;
for (size_t i = 0; i<nv && i<vc; ++i)
{
value[i] = nv[i];
}
if (vc > nc)
value[nc] = 0;
}
};
template<size_t N>
struct char_array_support_write_impl
{
//typedef ty value_type;
static inline void write(std::ostream& stream, std::string name, const char(&value)[N])
{
const char * str_value = value;
stream << boost::str(boost::format("\n<%s>%s</%s>") % name %str_value %name);
}
};
template<int N>
struct node_support_read_impl< char[N]>
{
typedef char value_type[N];
typedef char_array_support_read_impl<N> impl;
};
template<int N>
struct node_support_write_impl< char[N]>
{
typedef const char value_type[N];
typedef char_array_support_write_impl<N> impl;
};
template<typename ty>
struct container_seq_support_read_impl
{
//typedef ty value_type;
static void read(xml_node<char>& xml_value, ty& value)
{
value.clear();
xml_node<char> *peer = &xml_value;
while (peer)
{
typename ty::value_type item;
node_support_read<typename ty::value_type>::impl::read(*peer, item);
value.push_back(item);
peer = peer->next_sibling(xml_value.name());
}
}
};
template<typename ty>
struct container_seq_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string name, const value_type& value)
{
for (typename ty::const_iterator iter = value.cbegin(); iter != value.cend(); ++iter)
{
node_support_write<typename ty::value_type>::impl::write(stream, name, *iter);
}
}
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::list<ty, alloc_ty>>
{
typedef typename ::std::list<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::list<ty, alloc_ty>>
{
typedef typename ::std::list<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::deque<ty, alloc_ty>>
{
typedef typename ::std::deque<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::deque<ty, alloc_ty>>
{
typedef typename ::std::deque<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::vector<ty, alloc_ty>>
{
typedef typename ::std::vector<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::vector<ty, alloc_ty>>
{
typedef typename ::std::vector<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template <typename ty>
struct node_support_read
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_read_impl< value_type>::impl,
typename node_support_read_impl<value_type>::impl
>::type impl;
};
template <typename ty>
struct attribute_support_read
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_read_impl< value_type>::impl,
typename attribute_support_read_impl<value_type>::impl
>::type impl;
};
template <typename ty>
struct node_support_write
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_write_impl<value_type>::impl,
typename node_support_write_impl<value_type>::impl
>::type impl;
};
template <typename ty>
struct attribute_support_write
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_write_impl<value_type>::impl,
typename attribute_support_write_impl<value_type>::impl
>::type impl;
};
template<typename ty>
void axml_read_node(xml_node<char>& xml_value, ty& value)
{
node_support_read<ty>::impl::read(xml_value, value);
}
template<typename ty>
void axml_read_attribute(xml_attribute<char>& xml_value, ty& value)
{
attribute_support_read<ty>::impl::read(xml_value, value);
}
template< typename ty>
void axml_write_node(std::ostream& stream, std::string name, ty& value)
{
node_support_write<ty>::impl::write(stream, name, value);
}
template< typename ty>
void axml_write_attribute(std::ostream& stream, std::string name, ty& value)
{
attribute_support_write<ty>::impl::write(stream, name, value);
}
template<typename ty>
inline bool load_from_node(ty& value, const xml_node<char>& node)
{
return axml_read_node(node, value);
}
template<typename ty>
inline void load(ty& value, std::istream& stream)
{
xml_document<char> document;
// Load data into vector
stream.unsetf(std::ios::skipws);
std::vector<char> v(std::istreambuf_iterator<char>(stream.rdbuf()),
std::istreambuf_iterator<char>());
if (!stream.good() || v.empty())
{
document.clear();
throw std::exception("read xml error");
}
v.push_back(0); // zero-terminate
try
{
document.parse<0>(&v.front());
xml_node<char>* root_node = document.first_node();
axml_read_node(*root_node, value);
}
catch(...)
{
document.clear();
throw;
}
document.clear();
}
template<typename ty>
inline void save(ty& value, std::string root_name, std::ostream& stream)
{
stream << "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
axml_write_node(stream, root_name, value);
stream.flush();
if (!stream)
{
throw std::exception("write error");
}
}
}
}
#ifndef AXML
#define AXML_READ_MEMBER( r , v , elem ) \
member_name = BOOST_DO_STRINGIZE(elem);\
if (member_name[0] == '_')\
{\
xml_attribute<char>* attr = xml_value.first_attribute(member_name + 1);\
if (attr) {axml_read_attribute(*attr, value.elem);}\
}\
else\
{\
xml_node<char>* node = xml_value.first_node(member_name);\
if (node){axml_read_node(*node , value.elem);}\
}
#define AXML_WRITE_MEMBER( r ,v , elem ) \
member_name = BOOST_DO_STRINGIZE(elem);\
if (member_name[0] != '_')\
{\
axml_write_node(stream, member_name, value.elem); \
}
#define AXML_WRITE_ATTR( r ,v , elem ) \
member_name = BOOST_DO_STRINGIZE(elem);\
if (member_name[0] == '_')\
{\
axml_write_attribute(stream, member_name, value.elem); \
}
#define AXML(TYPE, MEMBERS)\
namespace boost\
{\
namespace axml\
{\
template <>\
struct node_support_read_impl<TYPE>\
{\
typedef TYPE value_type;\
typedef node_support_read_impl<TYPE> impl;\
static inline void read(const xml_node<char>& xml_value , value_type& value)\
{\
char * member_name = NULL;\
BOOST_PP_SEQ_FOR_EACH( AXML_READ_MEMBER , 0 , MEMBERS ) \
return;\
}\
};\
template <>\
struct node_support_write_impl<TYPE>\
{\
typedef TYPE value_type; \
typedef node_support_write_impl<TYPE> impl;\
static inline void write(std::ostream& stream, std::string name, const value_type& value)\
{\
stream << "\n<" << name;\
char * member_name = NULL;\
BOOST_PP_SEQ_FOR_EACH( AXML_WRITE_ATTR , 0 , MEMBERS ) \
stream << ">";\
BOOST_PP_SEQ_FOR_EACH( AXML_WRITE_MEMBER , 0 , MEMBERS ) \
stream << "\n</" << name << ">";\
return;\
}\
};\
}\
}
#endif
Properties解析Src
#pragma once
#include <string>
#include <vector>
#include <list>
#include <deque>
#include <iostream>
#include <exception>
#include <boost/cstdint.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/if.hpp>
#include <boost/format.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <boost/property_tree/detail/ptree_implementation.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/seq.hpp>
#include <boost/preprocessor/stringize.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <boost/algorithm/string.hpp>
namespace boost
{
namespace aprop
{
template <typename ty>
struct node_support_read_impl
{
typedef ty value_type;
typedef node_support_read_impl<ty> impl;
static void read(property_tree::ptree& aprop_value, value_type& value) {}
};
template <typename ty>
struct node_support_write_impl
{
typedef ty value_type;
typedef node_support_write_impl<ty> impl;
static void write(std::ostream& stream, std::string prefix, const value_type& value) {}
};
template <typename ty>
struct node_support_read;
template <typename ty>
struct node_support_write;
template<typename ty>
struct integer_arithmetic_support_read_impl
{
typedef ty value_type;
static void read(property_tree::ptree& aprop_value, value_type& value)
{
std::string str_value = aprop_value.data();
if (str_value.empty())
value = 0;
else
value = boost::lexical_cast<value_type>(str_value);
}
};
template<typename ty>
struct integer_arithmetic_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string prefix, const value_type& value)
{
stream << boost::str(boost::format("%s=%d") % prefix % value)<<std::endl;
}
};
template<typename ty>
struct float_arithmetic_support_read_impl
{
typedef ty value_type;
static void read(property_tree::ptree& aprop_value, value_type& value)
{
std::string str_value(aprop_value.data());
if (str_value.empty())
value = 0.0;
else
value = boost::lexical_cast<value_type>(str_value);
}
};
template<typename ty>
struct float_arithmetic_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string prefix, const value_type& value)
{
stream << boost::str(boost::format("%s=%f") % prefix % value) << std::endl;
}
};
template<>
struct integer_arithmetic_support_read_impl <bool>
{
typedef bool value_type;
static void read(property_tree::ptree& aprop_value, value_type& value)
{
std::string str_value(aprop_value.data());
if (str_value == "true")
value = true;
else
value = false;
}
};
template<>
struct integer_arithmetic_support_write_impl < bool >
{
typedef bool value_type;
static void write(std::ostream& stream, std::string prefix, const value_type& value)
{
std::string str_value = (value ? "true" : "false");
stream << boost::str(boost::format("%s=%s") % prefix % str_value) << std::endl;
}
};
template <typename ty>
struct arithmetic_support_read_impl
{
typedef ty value_type;
typedef typename ::boost::mpl::if_<
::boost::is_integral<value_type>,
integer_arithmetic_support_read_impl<value_type>,
float_arithmetic_support_read_impl<value_type>
>::type impl;
};
template <typename ty>
struct arithmetic_support_write_impl
{
typedef ty value_type;
typedef typename ::boost::mpl::if_<
::boost::is_integral<value_type>,
integer_arithmetic_support_write_impl<value_type>,
float_arithmetic_support_write_impl<value_type>
>::type impl;
};
template<typename ty>
struct string_support_read_impl
{
typedef ty value_type;
static void read(property_tree::ptree& aprop_value, value_type& value)
{
value = aprop_value.data();
}
};
template<typename ty>
struct string_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string prefix, const value_type& value)
{
stream << boost::str(boost::format("%s=%s") % prefix % value) << std::endl;
}
};
template<typename char_traits_ty, typename char_alloc_type>
struct node_support_read_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type> >
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_read_impl<value_type> impl;
};
template<typename char_traits_ty, typename char_alloc_type>
struct node_support_write_impl< ::std::basic_string<char, char_traits_ty, char_alloc_type> >
{
typedef ::std::basic_string<char, char_traits_ty, char_alloc_type> value_type;
typedef string_support_write_impl<value_type> impl;
};
template<typename ty>
struct container_seq_support_read_impl
{
//typedef ty value_type;
static void read(property_tree::ptree& aprop_value, ty& value)
{
value.clear();
for (property_tree::ptree::iterator it = aprop_value.begin();
it != aprop_value.end(); ++it)
{
typename ty::value_type item;
node_support_read<typename ty::value_type>::impl::read(it->second, item);
value.push_back(item);
}
}
};
template<typename ty>
struct container_seq_support_write_impl
{
typedef ty value_type;
static void write(std::ostream& stream, std::string prefix, const value_type& value)
{
for (int i = 0; i < value.size(); ++i)
{
node_support_write<typename ty::value_type>::impl::write(stream, prefix, value.at(i));
}
}
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::list<ty, alloc_ty> >
{
typedef typename ::std::list<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::list<ty, alloc_ty> >
{
typedef typename ::std::list<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::deque<ty, alloc_ty> >
{
typedef typename ::std::deque<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::deque<ty, alloc_ty> >
{
typedef typename ::std::deque<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_read_impl< ::std::vector<ty, alloc_ty> >
{
typedef typename ::std::vector<ty, alloc_ty> value_type;
typedef container_seq_support_read_impl<value_type> impl;
};
template<typename ty, typename alloc_ty>
struct node_support_write_impl< ::std::vector<ty, alloc_ty> >
{
typedef typename ::std::vector<ty, alloc_ty> value_type;
typedef container_seq_support_write_impl<value_type> impl;
};
template <typename ty>
struct node_support_read
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_read_impl< value_type>::impl,
typename node_support_read_impl<value_type>::impl
>::type impl;
};
template <typename ty>
struct node_support_write
{
typedef typename ::boost::remove_const<ty>::type value_type;
typedef typename ::boost::mpl::if_<
::boost::is_arithmetic<value_type>,
typename arithmetic_support_write_impl<value_type>::impl,
typename node_support_write_impl<value_type>::impl
>::type impl;
};
template<typename ty>
void aprop_read_node(property_tree::ptree& aprop_value, ty& value)
{
node_support_read<ty>::impl::read(aprop_value, value);
}
template< typename ty>
void aprop_write_node(std::ostream& stream, std::string prefix, ty& value)
{
node_support_write<ty>::impl::write(stream, prefix, value);
}
inline void print_tree(std::ostream& os,const property_tree::ptree& pt, int tab)
{
os << std::string(tab, ' ');
os << "{\n";
for (property_tree::ptree::const_iterator iter = pt.begin(); iter != pt.end(); ++iter)
{
if (!iter->second.empty())
{
os << std::string(tab+2, ' ');
os << iter->first << ":\n";
print_tree(os, iter->second, tab+2);
}
else
{
os << std::string(tab + 2, ' ');
os << iter->first << ":" << iter->second.data() << "\n";
}
}
os << std::string(tab, ' ');
os << "}\n";
}
template<typename ty>
inline void load(ty& value, std::istream& stream)
{
property_tree::ptree root;
// Load data into vector
// stream.unsetf(std::ios::skipws);
// std::vector<char> v(std::istreambuf_iterator<char>(stream.rdbuf()),
// std::istreambuf_iterator<char>());
// if (!stream.good() || v.empty())
// {
// throw std::runtime_error("read properties error");
// }
// v.push_back(0); // zero-terminate
try
{
int line_no = 0;
while (stream.good())
{
++line_no;
std::string line;
std::getline(stream, line);
if (!stream.good() && !stream.eof())
BOOST_PROPERTY_TREE_THROW(property_tree::file_parser_error(
"read error", "", line_no));
line = property_tree::detail::trim(line, stream.getloc());
if (line.empty() || line[0] == ';' || line[0] == '#')
continue;
typename std::string::size_type eqpos = line.find('=');
if (eqpos == std::string::npos)
BOOST_PROPERTY_TREE_THROW(property_tree::file_parser_error(
"missing '='", "", line_no));
std::string key = property_tree::detail::trim(
line.substr(0, eqpos), stream.getloc());
std::string data = property_tree::detail::trim(
line.substr(eqpos + 1, std::string::npos), stream.getloc());
boost::algorithm::replace_all(key,"[",".");
boost::algorithm::replace_all(key, "]", "");
root.add(key, data);
}
// std::stringstream os;
// print_tree(os, root, 0);
// std::string dump = os.str();
aprop_read_node(root, value);
}
catch (...)
{
throw;
}
}
template<typename ty>
inline void save(ty& value, std::ostream& stream)
{
aprop_write_node(stream, "", value);
stream.flush();
if (!stream)
{
throw std::runtime_error("write error");
}
}
}
}
#ifndef APROP
#define APROP_READ_MEMBER( r , v , elem ) \
member_name = BOOST_DO_STRINGIZE(elem);\
itor = aprop_value.find(member_name);\
if (itor != aprop_value.not_found())\
{aprop_read_node(itor->second, value.elem);}
#define APROP_WRITE_MEMBER( r ,v , elem ) \
member_name = BOOST_DO_STRINGIZE(elem);\
if (prefix.empty())\
{aprop_write_node(stream, member_name, value.elem);}\
else\
{aprop_write_node(stream, prefix + "." + member_name, value.elem);}
#define APROP(TYPE, MEMBERS)\
namespace boost\
{\
namespace aprop\
{\
template <>\
struct node_support_read_impl<TYPE>\
{\
typedef TYPE value_type;\
typedef node_support_read_impl<TYPE> impl;\
static inline void read(property_tree::ptree& aprop_value, value_type& value)\
{\
std::string member_name; \
property_tree::ptree::assoc_iterator itor;\
BOOST_PP_SEQ_FOR_EACH( APROP_READ_MEMBER , 0 , MEMBERS ) \
return;\
}\
};\
template <>\
struct node_support_write_impl<TYPE>\
{\
typedef TYPE value_type;\
typedef node_support_write_impl<TYPE> impl;\
static inline void write(std::ostream& stream, std::string prefix, const value_type& value)\
{\
std::string member_name;\
BOOST_PP_SEQ_FOR_EACH( APROP_WRITE_MEMBER , 0 , MEMBERS ) \
return;\
}\
};\
}\
}
#endif