From ab81a250733097341c6191bc9ce1ce58b4b31d89 Mon Sep 17 00:00:00 2001 From: Peter Boyle Date: Thu, 20 Aug 2015 16:21:26 +0100 Subject: [PATCH] XMLReader implementation and a virtual Reader/Writer template framework. Test_serialisation has an example of *code* *free* object serialisation to both ostream and to XML using macro magic. Implementing TextReader/TextWriter, YAML, JSON etc.. should be trivial and we can use configure time options to select the default "Reader" typedef. Present done with "using XMLPolicy::Reader" to pick up the default serialisation strategy. --- lib/Grid.h | 2 +- lib/Make.inc | 4 +- lib/Serialisation.h | 6 + lib/pugixml/{pugixml.cpp => pugixml.cc} | 2 +- lib/pugixml/{pugixml.hpp => pugixml.h} | 2 +- lib/{ => serialisation}/MacroMagic.h | 19 ++- lib/serialisation/Reader.h | 81 ++++++++++++ lib/serialisation/XMLReader.h | 168 ++++++++++++++++++++++++ tests/Make.inc | 6 +- tests/Test_serialisation.cc | 65 +++++++++ 10 files changed, 348 insertions(+), 7 deletions(-) create mode 100644 lib/Serialisation.h rename lib/pugixml/{pugixml.cpp => pugixml.cc} (99%) rename lib/pugixml/{pugixml.hpp => pugixml.h} (99%) rename lib/{ => serialisation}/MacroMagic.h (85%) create mode 100644 lib/serialisation/Reader.h create mode 100644 lib/serialisation/XMLReader.h create mode 100644 tests/Test_serialisation.cc diff --git a/lib/Grid.h b/lib/Grid.h index 624bc5a7..619f6208 100644 --- a/lib/Grid.h +++ b/lib/Grid.h @@ -30,7 +30,7 @@ /////////////////// // Grid headers /////////////////// -#include +#include #include #include #include diff --git a/lib/Make.inc b/lib/Make.inc index 789c8476..6fb4a651 100644 --- a/lib/Make.inc +++ b/lib/Make.inc @@ -1,4 +1,4 @@ -HFILES=./algorithms/approx/bigfloat.h ./algorithms/approx/bigfloat_double.h ./algorithms/approx/Chebyshev.h ./algorithms/approx/MultiShiftFunction.h ./algorithms/approx/Remez.h ./algorithms/approx/Zolotarev.h ./algorithms/CoarsenedMatrix.h ./algorithms/iterative/AdefGeneric.h ./algorithms/iterative/ConjugateGradient.h ./algorithms/iterative/ConjugateGradientMultiShift.h ./algorithms/iterative/ConjugateResidual.h ./algorithms/iterative/NormalEquations.h ./algorithms/iterative/PrecConjugateResidual.h ./algorithms/iterative/PrecGeneralisedConjugateResidual.h ./algorithms/iterative/SchurRedBlack.h ./algorithms/LinearOperator.h ./algorithms/Preconditioner.h ./algorithms/SparseMatrix.h ./Algorithms.h ./AlignedAllocator.h ./cartesian/Cartesian_base.h ./cartesian/Cartesian_full.h ./cartesian/Cartesian_red_black.h ./Cartesian.h ./communicator/Communicator_base.h ./Communicator.h ./Config.h ./cshift/Cshift_common.h ./cshift/Cshift_mpi.h ./cshift/Cshift_none.h ./Cshift.h ./Grid.h ./Init.h ./lattice/Lattice_arith.h ./lattice/Lattice_base.h ./lattice/Lattice_comparison.h ./lattice/Lattice_comparison_utils.h ./lattice/Lattice_conformable.h ./lattice/Lattice_coordinate.h ./lattice/Lattice_ET.h ./lattice/Lattice_local.h ./lattice/Lattice_overload.h ./lattice/Lattice_peekpoke.h ./lattice/Lattice_reality.h ./lattice/Lattice_reduction.h ./lattice/Lattice_rng.h ./lattice/Lattice_trace.h ./lattice/Lattice_transfer.h ./lattice/Lattice_transpose.h ./lattice/Lattice_unary.h ./lattice/Lattice_where.h ./Lattice.h ./Log.h ./MacroMagic.h ./Old/Tensor_peek.h ./Old/Tensor_poke.h ./parallelIO/NerscIO.h ./qcd/action/ActionBase.h ./qcd/action/ActionParams.h ./qcd/action/Actions.h ./qcd/action/fermion/CayleyFermion5D.h ./qcd/action/fermion/ContinuedFractionFermion5D.h ./qcd/action/fermion/DomainWallFermion.h ./qcd/action/fermion/FermionOperator.h ./qcd/action/fermion/FermionOperatorImpl.h ./qcd/action/fermion/g5HermitianLinop.h ./qcd/action/fermion/MobiusFermion.h ./qcd/action/fermion/MobiusZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonCayleyTanhFermion.h ./qcd/action/fermion/OverlapWilsonCayleyZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonContfracTanhFermion.h ./qcd/action/fermion/OverlapWilsonContfracZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionTanhFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionZolotarevFermion.h ./qcd/action/fermion/PartialFractionFermion5D.h ./qcd/action/fermion/ScaledShamirFermion.h ./qcd/action/fermion/ShamirZolotarevFermion.h ./qcd/action/fermion/WilsonCompressor.h ./qcd/action/fermion/WilsonFermion.h ./qcd/action/fermion/WilsonFermion5D.h ./qcd/action/fermion/WilsonKernels.h ./qcd/action/gauge/WilsonGaugeAction.h ./qcd/action/pseudofermion/EvenOddSchurDifferentiable.h ./qcd/action/pseudofermion/OneFlavourEvenOddRational.h ./qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h ./qcd/action/pseudofermion/OneFlavourRational.h ./qcd/action/pseudofermion/OneFlavourRationalRatio.h ./qcd/action/pseudofermion/TwoFlavour.h ./qcd/action/pseudofermion/TwoFlavourEvenOdd.h ./qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h ./qcd/action/pseudofermion/TwoFlavourRatio.h ./qcd/hmc/HMC.h ./qcd/hmc/integrators/Integrator.h ./qcd/hmc/integrators/Integrator_algorithm.h ./qcd/QCD.h ./qcd/spin/Dirac.h ./qcd/spin/TwoSpinor.h ./qcd/utils/CovariantCshift.h ./qcd/utils/LinalgUtils.h ./qcd/utils/SpaceTimeGrid.h ./qcd/utils/SUn.h ./qcd/utils/WilsonLoops.h ./simd/Grid_avx.h ./simd/Grid_avx512.h ./simd/Grid_empty.h ./simd/Grid_neon.h ./simd/Grid_qpx.h ./simd/Grid_sse4.h ./simd/Grid_vector_types.h ./simd/Grid_vector_unops.h ./Simd.h ./stencil/Lebesgue.h ./Stencil.h ./tensors/Tensor_arith.h ./tensors/Tensor_arith_add.h ./tensors/Tensor_arith_mac.h ./tensors/Tensor_arith_mul.h ./tensors/Tensor_arith_scalar.h ./tensors/Tensor_arith_sub.h ./tensors/Tensor_class.h ./tensors/Tensor_determinant.h ./tensors/Tensor_exp.h ./tensors/Tensor_extract_merge.h ./tensors/Tensor_index.h ./tensors/Tensor_inner.h ./tensors/Tensor_logical.h ./tensors/Tensor_outer.h ./tensors/Tensor_reality.h ./tensors/Tensor_Ta.h ./tensors/Tensor_trace.h ./tensors/Tensor_traits.h ./tensors/Tensor_transpose.h ./tensors/Tensor_unary.h ./Tensors.h ./Threads.h ./Timer.h +HFILES=./algorithms/approx/bigfloat.h ./algorithms/approx/bigfloat_double.h ./algorithms/approx/Chebyshev.h ./algorithms/approx/MultiShiftFunction.h ./algorithms/approx/Remez.h ./algorithms/approx/Zolotarev.h ./algorithms/CoarsenedMatrix.h ./algorithms/iterative/AdefGeneric.h ./algorithms/iterative/ConjugateGradient.h ./algorithms/iterative/ConjugateGradientMultiShift.h ./algorithms/iterative/ConjugateResidual.h ./algorithms/iterative/NormalEquations.h ./algorithms/iterative/PrecConjugateResidual.h ./algorithms/iterative/PrecGeneralisedConjugateResidual.h ./algorithms/iterative/SchurRedBlack.h ./algorithms/LinearOperator.h ./algorithms/Preconditioner.h ./algorithms/SparseMatrix.h ./Algorithms.h ./AlignedAllocator.h ./cartesian/Cartesian_base.h ./cartesian/Cartesian_full.h ./cartesian/Cartesian_red_black.h ./Cartesian.h ./communicator/Communicator_base.h ./Communicator.h ./Config.h ./cshift/Cshift_common.h ./cshift/Cshift_mpi.h ./cshift/Cshift_none.h ./Cshift.h ./Grid.h ./Init.h ./lattice/Lattice_arith.h ./lattice/Lattice_base.h ./lattice/Lattice_comparison.h ./lattice/Lattice_comparison_utils.h ./lattice/Lattice_conformable.h ./lattice/Lattice_coordinate.h ./lattice/Lattice_ET.h ./lattice/Lattice_local.h ./lattice/Lattice_overload.h ./lattice/Lattice_peekpoke.h ./lattice/Lattice_reality.h ./lattice/Lattice_reduction.h ./lattice/Lattice_rng.h ./lattice/Lattice_trace.h ./lattice/Lattice_transfer.h ./lattice/Lattice_transpose.h ./lattice/Lattice_unary.h ./lattice/Lattice_where.h ./Lattice.h ./Log.h ./Old/Tensor_peek.h ./Old/Tensor_poke.h ./parallelIO/NerscIO.h ./pugixml/pugixml.h ./qcd/action/ActionBase.h ./qcd/action/ActionParams.h ./qcd/action/Actions.h ./qcd/action/fermion/CayleyFermion5D.h ./qcd/action/fermion/ContinuedFractionFermion5D.h ./qcd/action/fermion/DomainWallFermion.h ./qcd/action/fermion/FermionOperator.h ./qcd/action/fermion/FermionOperatorImpl.h ./qcd/action/fermion/g5HermitianLinop.h ./qcd/action/fermion/MobiusFermion.h ./qcd/action/fermion/MobiusZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonCayleyTanhFermion.h ./qcd/action/fermion/OverlapWilsonCayleyZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonContfracTanhFermion.h ./qcd/action/fermion/OverlapWilsonContfracZolotarevFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionTanhFermion.h ./qcd/action/fermion/OverlapWilsonPartialFractionZolotarevFermion.h ./qcd/action/fermion/PartialFractionFermion5D.h ./qcd/action/fermion/ScaledShamirFermion.h ./qcd/action/fermion/ShamirZolotarevFermion.h ./qcd/action/fermion/WilsonCompressor.h ./qcd/action/fermion/WilsonFermion.h ./qcd/action/fermion/WilsonFermion5D.h ./qcd/action/fermion/WilsonKernels.h ./qcd/action/gauge/WilsonGaugeAction.h ./qcd/action/pseudofermion/EvenOddSchurDifferentiable.h ./qcd/action/pseudofermion/OneFlavourEvenOddRational.h ./qcd/action/pseudofermion/OneFlavourEvenOddRationalRatio.h ./qcd/action/pseudofermion/OneFlavourRational.h ./qcd/action/pseudofermion/OneFlavourRationalRatio.h ./qcd/action/pseudofermion/TwoFlavour.h ./qcd/action/pseudofermion/TwoFlavourEvenOdd.h ./qcd/action/pseudofermion/TwoFlavourEvenOddRatio.h ./qcd/action/pseudofermion/TwoFlavourRatio.h ./qcd/hmc/HMC.h ./qcd/hmc/integrators/Integrator.h ./qcd/hmc/integrators/Integrator_algorithm.h ./qcd/QCD.h ./qcd/spin/Dirac.h ./qcd/spin/TwoSpinor.h ./qcd/utils/CovariantCshift.h ./qcd/utils/LinalgUtils.h ./qcd/utils/SpaceTimeGrid.h ./qcd/utils/SUn.h ./qcd/utils/WilsonLoops.h ./serialisation/MacroMagic.h ./serialisation/Reader.h ./serialisation/XMLReader.h ./simd/Grid_avx.h ./simd/Grid_avx512.h ./simd/Grid_empty.h ./simd/Grid_neon.h ./simd/Grid_qpx.h ./simd/Grid_sse4.h ./simd/Grid_vector_types.h ./simd/Grid_vector_unops.h ./Simd.h ./stencil/Lebesgue.h ./Stencil.h ./tensors/Tensor_arith.h ./tensors/Tensor_arith_add.h ./tensors/Tensor_arith_mac.h ./tensors/Tensor_arith_mul.h ./tensors/Tensor_arith_scalar.h ./tensors/Tensor_arith_sub.h ./tensors/Tensor_class.h ./tensors/Tensor_determinant.h ./tensors/Tensor_exp.h ./tensors/Tensor_extract_merge.h ./tensors/Tensor_index.h ./tensors/Tensor_inner.h ./tensors/Tensor_logical.h ./tensors/Tensor_outer.h ./tensors/Tensor_reality.h ./tensors/Tensor_Ta.h ./tensors/Tensor_trace.h ./tensors/Tensor_traits.h ./tensors/Tensor_transpose.h ./tensors/Tensor_unary.h ./Tensors.h ./Threads.h ./Timer.h -CCFILES=./algorithms/approx/MultiShiftFunction.cc ./algorithms/approx/Remez.cc ./algorithms/approx/Zolotarev.cc ./Init.cc ./Log.cc ./qcd/action/fermion/CayleyFermion5D.cc ./qcd/action/fermion/ContinuedFractionFermion5D.cc ./qcd/action/fermion/PartialFractionFermion5D.cc ./qcd/action/fermion/WilsonFermion.cc ./qcd/action/fermion/WilsonFermion5D.cc ./qcd/action/fermion/WilsonKernels.cc ./qcd/action/fermion/WilsonKernelsHand.cc ./qcd/hmc/HMC.cc ./qcd/hmc/integrators/Integrator.cc ./qcd/spin/Dirac.cc ./qcd/utils/SpaceTimeGrid.cc ./stencil/Lebesgue.cc ./stencil/Stencil_common.cc +CCFILES=./algorithms/approx/MultiShiftFunction.cc ./algorithms/approx/Remez.cc ./algorithms/approx/Zolotarev.cc ./Init.cc ./Log.cc ./pugixml/pugixml.cc ./qcd/action/fermion/CayleyFermion5D.cc ./qcd/action/fermion/ContinuedFractionFermion5D.cc ./qcd/action/fermion/PartialFractionFermion5D.cc ./qcd/action/fermion/WilsonFermion.cc ./qcd/action/fermion/WilsonFermion5D.cc ./qcd/action/fermion/WilsonKernels.cc ./qcd/action/fermion/WilsonKernelsHand.cc ./qcd/hmc/HMC.cc ./qcd/hmc/integrators/Integrator.cc ./qcd/spin/Dirac.cc ./qcd/utils/SpaceTimeGrid.cc ./stencil/Lebesgue.cc ./stencil/Stencil_common.cc diff --git a/lib/Serialisation.h b/lib/Serialisation.h new file mode 100644 index 00000000..da90eae1 --- /dev/null +++ b/lib/Serialisation.h @@ -0,0 +1,6 @@ +#ifndef GRID_SERIALISATION_H +#define GRID_SERIALISATION_H + +#include // subdir aggregate + +#endif diff --git a/lib/pugixml/pugixml.cpp b/lib/pugixml/pugixml.cc similarity index 99% rename from lib/pugixml/pugixml.cpp rename to lib/pugixml/pugixml.cc index 07f3a336..525d1419 100644 --- a/lib/pugixml/pugixml.cpp +++ b/lib/pugixml/pugixml.cc @@ -14,7 +14,7 @@ #ifndef SOURCE_PUGIXML_CPP #define SOURCE_PUGIXML_CPP -#include "pugixml.hpp" +#include #include #include diff --git a/lib/pugixml/pugixml.hpp b/lib/pugixml/pugixml.h similarity index 99% rename from lib/pugixml/pugixml.hpp rename to lib/pugixml/pugixml.h index cdd24b6d..346cefdd 100644 --- a/lib/pugixml/pugixml.hpp +++ b/lib/pugixml/pugixml.h @@ -17,7 +17,7 @@ #endif // Include user configuration file (this can define various configuration macros) -#include "pugiconfig.hpp" +#include #ifndef HEADER_PUGIXML_HPP #define HEADER_PUGIXML_HPP diff --git a/lib/MacroMagic.h b/lib/serialisation/MacroMagic.h similarity index 85% rename from lib/MacroMagic.h rename to lib/serialisation/MacroMagic.h index f0762337..c5b32528 100644 --- a/lib/MacroMagic.h +++ b/lib/serialisation/MacroMagic.h @@ -66,6 +66,8 @@ #define GRID_MACRO_MEMBER(A,B) A B; #define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" "#B <<" = "<< obj. B <<" ; " < friend void write(Writer &WR,const std::string &s, const cname &obj){ \ + push(WR,s);\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_WRITE_MEMBER,__VA_ARGS__)) \ + pop(WR);\ + } \ + \ + \ + template friend void read(Reader &RD,const std::string &s, cname &obj){ \ + push(RD,s);\ + GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_READ_MEMBER,__VA_ARGS__)) \ + pop(RD);\ + } \ + \ + \ + friend std::ostream & operator << (std::ostream &os, const cname &obj ) { \ os<<"class "<<#cname<<" {"< + +namespace Grid { + +// Generic reader writer interface + +template< class Writer> void push(Writer & WR,const std::string &s) { WR.push(s);} +template< class Writer> void push(Writer & WR,const char *s) { WR.push(std::string(s));} +template< class Writer> void pop (Writer & WR) { WR.pop();} + +template< class Writer> void write(Writer& wr, const std::string& s,const char * output ) { wr.iwrite(s,std::string(output)); }; +template< class Writer> void write(Writer& wr, const std::string& s,const std::string &output) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, int16_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, uint16_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, int32_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, uint32_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, int64_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, uint64_t output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, float output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, double output ) { wr.iwrite(s,output); }; +template< class Writer> void write(Writer& wr, const std::string& s, bool output ) { wr.iwrite(s,output); }; + +template< class Reader> void read(Reader& rd, const std::string& s,std::string &output) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, int16_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, uint16_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, int32_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, uint32_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, int64_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, uint64_t &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, float &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, double &output ) { rd.iread(s,output); }; +template< class Reader> void read(Reader& rd, const std::string& s, bool &output ) { rd.iread(s,output); }; + + +template +void write(Writer& wr, const std::string& s,const std::vector output ) { + push(wr,s); + for(int i=0;i +void read(Reader& rd, const std::string& s,std::vector &output ) { + rd.iread(s,output); +}; + +template < class T > +inline std::ostream& operator << (std::ostream& os, const std::vector& v) +{ + os << "["; + for (typename std::vector::const_iterator ii = v.begin(); ii != v.end(); ++ii) + { + os << " " << *ii; + } + os << " ]"; + return os; +} + +} + +// Todo: +//#include +//#include +//#include +//#include +#include + +namespace Grid { + +using XMLPolicy::Reader; +using XMLPolicy::Writer; + +} + +#endif diff --git a/lib/serialisation/XMLReader.h b/lib/serialisation/XMLReader.h new file mode 100644 index 00000000..ddda1d46 --- /dev/null +++ b/lib/serialisation/XMLReader.h @@ -0,0 +1,168 @@ +#ifndef GRID_SERIALISATION_XML_READER_H +#define GRID_SERIALISATION_XML_READER_H + +#include +#include +#include +#include +#include +#include +#include + +#include "pugixml/pugixml.h" + + +namespace Grid { + +class XMLWriter { +private: + + pugi::xml_document doc; + pugi::xml_node node; + std::string file; + +public: + + XMLWriter(const std::string &_file) : file(_file) + { + node=doc.append_child(); + node.set_name("document"); + } + + ~XMLWriter() + { + // simple_walker walker; + // doc.traverse(walker); + + doc.save_file(file.c_str()," "); + } + + void push(const std::string &s) + { + node = node.append_child(s.c_str()); + } + void pop(void) { + node = node.parent(); + } + + void iwrite( const std::string& s,const std::string &output ) { + pugi::xml_node leaf=node.append_child(s.c_str()); + leaf.append_child(pugi::node_pcdata).set_value(output.c_str()); + }; + void iwrite( const std::string& s, int16_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, uint16_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, int32_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, uint32_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, int64_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, uint64_t output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, float output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, double output ) { writeInternal(s,output); }; + void iwrite( const std::string& s, bool output ) { writeInternal(s,output); }; + +private: + template void writeInternal( const std::string& s, T output ){ + std::ostringstream os; + os << std::boolalpha << output; + iwrite(s,os.str()); + } + +}; + + +class XMLReader { +private: + + pugi::xml_document doc; + pugi::xml_node node; + +public: + + + XMLReader(const std::string &_file) + { + pugi::xml_parse_result result = doc.load_file(_file.c_str()); + + if ( !result ) { + std::cout << "XML error description: " << result.description() << "\n"; + std::cout << "XML error offset: " << result.offset << "\n"; + } + + assert(result); + + // simple_walker walker; + // doc.traverse(walker); + + node= doc.child("document"); + } + + ~XMLReader() + { + } + + void iread( const std::string& s,std::string &output ) { + output=node.child(s.c_str()).first_child().value(); + }; + void push(const std::string &s) + { + node = node.child(s.c_str()); + } + void pop(void) { + node = node.parent(); + } + + template + void iread( const std::string& s, std::vector &output ) { + output.resize(0); + + T tmp; + push(s); + int i=0; + for(pugi::xml_node it=node.first_child(); it; it = it.next_sibling() ){ + std::ostringstream oss; oss << "elem" << i; + read(*this,oss.str(),tmp); + output.push_back(tmp); + i++; + } + pop(); + + }; + + void iread( const std::string& s, int16_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, uint16_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, int32_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, uint32_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, int64_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, uint64_t &output ) { readInternal(s,output); }; + void iread( const std::string& s, float &output ) { readInternal(s,output); }; + void iread( const std::string& s, double &output ) { readInternal(s,output); }; + void iread( const std::string& s, bool &output ) { readInternal(s,output); }; + + +private: + + template void readInternal( const std::string& path, T &output ){ + std::string asString; + iread(path,asString); + convert(asString,output); + } + + template void convert(const std::string &asString,T &output) + { + std::istringstream is(asString); is.exceptions(std::ios::failbit); + try { + is >> std::boolalpha >> output; + } catch(std::istringstream::failure e) { + std::cerr << "XML read failure on "<<" "< + +using namespace Grid; + +class myclass { +public: + + GRID_DECL_CLASS_MEMBERS(myclass, + int, x, + double, y, + bool , b, + std::string, name, + std::vector, array, + std::vector >, twodimarray, + ); + + myclass() : array(4,5.0), twodimarray(3,std::vector(2,2.0)) { + x=1; + y=2; + b=false; + name="bother said pooh"; + } + +}; + + +uint16_t i16 = 1; +uint16_t u16 = 2; +uint32_t i32 = 3; +uint32_t u32 = 4; +uint64_t i64 = 5; +uint64_t u64 = 6; +float f = M_PI; +double d = 2*M_PI; +bool b = false; + +int main(int argc,char **argv) +{ + { + Writer WR("bother.xml"); + + push(WR,"BasicTypes"); + write(WR,"i16",i16); + write(WR,"u16",u16); + write(WR,"i32",i32); + write(WR,"i32",u32); + write(WR,"i64",i64); + write(WR,"i64",u64); + write(WR,"f",f); + write(WR,"d",d); + write(WR,"b",b); + pop(WR); + + myclass obj; + write(WR,"obj",obj); + + }; + + Reader RD("bother2.xml"); + + myclass copy; + + read(RD,"obj",copy); + std::cout << "Loaded " << copy<