mirror of
https://github.com/paboyle/Grid.git
synced 2025-06-18 15:57:05 +01:00
Hadrons: moving Hadrons to root directory, build system improvements
This commit is contained in:
344
Grid/serialisation/BaseIO.h
Normal file
344
Grid/serialisation/BaseIO.h
Normal file
@ -0,0 +1,344 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/BaseIO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu <guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_ABSTRACT_READER_H
|
||||
#define GRID_SERIALISATION_ABSTRACT_READER_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <Grid/tensors/Tensors.h>
|
||||
#include <Grid/serialisation/VectorUtils.h>
|
||||
|
||||
namespace Grid {
|
||||
// Abstract writer/reader classes ////////////////////////////////////////////
|
||||
// static polymorphism implemented using CRTP idiom
|
||||
class Serializable;
|
||||
|
||||
// Static abstract writer
|
||||
template <typename T>
|
||||
class Writer
|
||||
{
|
||||
public:
|
||||
Writer(void);
|
||||
virtual ~Writer(void) = default;
|
||||
void push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
write(const std::string& s, const U &output);
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||
write(const std::string& s, const U &output);
|
||||
template <typename U>
|
||||
void write(const std::string &s, const iScalar<U> &output);
|
||||
template <typename U, int N>
|
||||
void write(const std::string &s, const iVector<U, N> &output);
|
||||
template <typename U, int N>
|
||||
void write(const std::string &s, const iMatrix<U, N> &output);
|
||||
void scientificFormat(const bool set);
|
||||
bool isScientific(void);
|
||||
void setPrecision(const unsigned int prec);
|
||||
unsigned int getPrecision(void);
|
||||
private:
|
||||
T *upcast;
|
||||
bool scientific_{false};
|
||||
unsigned int prec_{0};
|
||||
};
|
||||
|
||||
// Static abstract reader
|
||||
template <typename T>
|
||||
class Reader
|
||||
{
|
||||
public:
|
||||
Reader(void);
|
||||
virtual ~Reader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
read(const std::string& s, U &output);
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||
read(const std::string& s, U &output);
|
||||
template <typename U>
|
||||
void read(const std::string &s, iScalar<U> &output);
|
||||
template <typename U, int N>
|
||||
void read(const std::string &s, iVector<U, N> &output);
|
||||
template <typename U, int N>
|
||||
void read(const std::string &s, iMatrix<U, N> &output);
|
||||
protected:
|
||||
template <typename U>
|
||||
void fromString(U &output, const std::string &s);
|
||||
private:
|
||||
T *upcast;
|
||||
};
|
||||
|
||||
// What is the vtype
|
||||
template<typename T> struct isReader {
|
||||
static const bool value = false;
|
||||
};
|
||||
template<typename T> struct isWriter {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
// Writer template implementation
|
||||
template <typename T>
|
||||
Writer<T>::Writer(void)
|
||||
{
|
||||
upcast = static_cast<T *>(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::push(const std::string &s)
|
||||
{
|
||||
upcast->push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::pop(void)
|
||||
{
|
||||
upcast->pop();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
Writer<T>::write(const std::string &s, const U &output)
|
||||
{
|
||||
U::write(*this, s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||
Writer<T>::write(const std::string &s, const U &output)
|
||||
{
|
||||
upcast->writeDefault(s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Writer<T>::write(const std::string &s, const iScalar<U> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Writer<T>::write(const std::string &s, const iVector<U, N> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Writer<T>::write(const std::string &s, const iMatrix<U, N> &output)
|
||||
{
|
||||
upcast->writeDefault(s, tensorToVec(output));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::scientificFormat(const bool set)
|
||||
{
|
||||
scientific_ = set;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Writer<T>::isScientific(void)
|
||||
{
|
||||
return scientific_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Writer<T>::setPrecision(const unsigned int prec)
|
||||
{
|
||||
prec_ = prec;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
unsigned int Writer<T>::getPrecision(void)
|
||||
{
|
||||
return prec_;
|
||||
}
|
||||
|
||||
// Reader template implementation
|
||||
template <typename T>
|
||||
Reader<T>::Reader(void)
|
||||
{
|
||||
upcast = static_cast<T *>(this);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Reader<T>::push(const std::string &s)
|
||||
{
|
||||
return upcast->push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void Reader<T>::pop(void)
|
||||
{
|
||||
upcast->pop();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<std::is_base_of<Serializable, U>::value, void>::type
|
||||
Reader<T>::read(const std::string &s, U &output)
|
||||
{
|
||||
U::read(*this, s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
typename std::enable_if<!std::is_base_of<Serializable, U>::value, void>::type
|
||||
Reader<T>::read(const std::string &s, U &output)
|
||||
{
|
||||
upcast->readDefault(s, output);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Reader<T>::read(const std::string &s, iScalar<U> &output)
|
||||
{
|
||||
typename TensorToVec<iScalar<U>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Reader<T>::read(const std::string &s, iVector<U, N> &output)
|
||||
{
|
||||
typename TensorToVec<iVector<U, N>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U, int N>
|
||||
void Reader<T>::read(const std::string &s, iMatrix<U, N> &output)
|
||||
{
|
||||
typename TensorToVec<iMatrix<U, N>>::type v;
|
||||
|
||||
upcast->readDefault(s, v);
|
||||
vecToTensor(output, v);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
template <typename U>
|
||||
void Reader<T>::fromString(U &output, const std::string &s)
|
||||
{
|
||||
std::istringstream is(s);
|
||||
|
||||
is.exceptions(std::ios::failbit);
|
||||
try
|
||||
{
|
||||
is >> std::boolalpha >> output;
|
||||
}
|
||||
catch(std::ios_base::failure &e)
|
||||
{
|
||||
std::cerr << "numerical conversion failure on '" << s << "' ";
|
||||
std::cerr << "(typeid: " << typeid(U).name() << ")" << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// serializable base class ///////////////////////////////////////////////////
|
||||
class Serializable
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
static inline void write(Writer<T> &WR,const std::string &s,
|
||||
const Serializable &obj)
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
static inline void read(Reader<T> &RD,const std::string &s,
|
||||
Serializable &obj)
|
||||
{}
|
||||
|
||||
friend inline std::ostream & operator<<(std::ostream &os,
|
||||
const Serializable &obj)
|
||||
{
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
// Generic writer interface //////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline void push(Writer<T> &w, const std::string &s) {
|
||||
w.push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void push(Writer<T> &w, const char *s)
|
||||
{
|
||||
w.push(std::string(s));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pop(Writer<T> &w)
|
||||
{
|
||||
w.pop();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void write(Writer<T> &w, const std::string& s, const U &output)
|
||||
{
|
||||
w.write(s, output);
|
||||
}
|
||||
|
||||
// Generic reader interface //////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
inline bool push(Reader<T> &r, const std::string &s)
|
||||
{
|
||||
return r.push(s);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool push(Reader<T> &r, const char *s)
|
||||
{
|
||||
return r.push(std::string(s));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void pop(Reader<T> &r)
|
||||
{
|
||||
r.pop();
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
inline void read(Reader<T> &r, const std::string &s, U &output)
|
||||
{
|
||||
r.read(s, output);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
70
Grid/serialisation/BinaryIO.cc
Normal file
70
Grid/serialisation/BinaryIO.cc
Normal file
@ -0,0 +1,70 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/BinaryIO.cc
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/GridCore.h>
|
||||
|
||||
using namespace Grid;
|
||||
|
||||
// Writer implementation ///////////////////////////////////////////////////////
|
||||
BinaryWriter::BinaryWriter(const std::string &fileName)
|
||||
: file_(fileName, std::ios::binary|std::ios::out)
|
||||
{}
|
||||
|
||||
template <>
|
||||
void BinaryWriter::writeDefault(const std::string &s, const std::string &x)
|
||||
{
|
||||
uint64_t sz = x.size();
|
||||
|
||||
write("", sz);
|
||||
for (uint64_t i = 0; i < sz; ++i)
|
||||
{
|
||||
write("", x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void BinaryWriter::writeDefault(const std::string &s, const char *x)
|
||||
{
|
||||
std::string sx(x);
|
||||
|
||||
writeDefault(s, sx);
|
||||
}
|
||||
|
||||
// Reader implementation ///////////////////////////////////////////////////////
|
||||
BinaryReader::BinaryReader(const std::string &fileName)
|
||||
: file_(fileName, std::ios::binary|std::ios::in)
|
||||
{}
|
||||
|
||||
template <>
|
||||
void BinaryReader::readDefault(const std::string &s, std::string &output)
|
||||
{
|
||||
uint64_t sz;
|
||||
|
||||
read("", sz);
|
||||
output.resize(sz);
|
||||
file_.read((char *)output.data(), sz);
|
||||
}
|
119
Grid/serialisation/BinaryIO.h
Normal file
119
Grid/serialisation/BinaryIO.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/BinaryIO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_BINARY_READER_H
|
||||
#define GRID_SERIALISATION_BINARY_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace Grid {
|
||||
|
||||
class BinaryWriter: public Writer<BinaryWriter>
|
||||
{
|
||||
public:
|
||||
BinaryWriter(const std::string &fileName);
|
||||
virtual ~BinaryWriter(void) = default;
|
||||
void push(const std::string &s) {};
|
||||
void pop(void) {};
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
void writeDefault(const std::string &s, const char *x);
|
||||
private:
|
||||
std::ofstream file_;
|
||||
};
|
||||
|
||||
class BinaryReader: public Reader<BinaryReader>
|
||||
{
|
||||
public:
|
||||
BinaryReader(const std::string &fileName);
|
||||
virtual ~BinaryReader(void) = default;
|
||||
bool push(const std::string &s) {return true;}
|
||||
void pop(void) {};
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::vector<U> &output);
|
||||
private:
|
||||
std::ifstream file_;
|
||||
};
|
||||
|
||||
// Writer template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void BinaryWriter::writeDefault(const std::string &s, const U &x)
|
||||
{
|
||||
file_.write((char *)&x, sizeof(U));
|
||||
}
|
||||
|
||||
template <>
|
||||
void BinaryWriter::writeDefault(const std::string &s, const std::string &x);
|
||||
|
||||
template <typename U>
|
||||
void BinaryWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
uint64_t sz = x.size();
|
||||
|
||||
write("", sz);
|
||||
for (uint64_t i = 0; i < sz; ++i)
|
||||
{
|
||||
write("", x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void BinaryReader::readDefault(const std::string &s, U &output)
|
||||
{
|
||||
file_.read((char *)&output, sizeof(U));
|
||||
}
|
||||
|
||||
template <>
|
||||
void BinaryReader::readDefault(const std::string &s, std::string &output);
|
||||
|
||||
template <typename U>
|
||||
void BinaryReader::readDefault(const std::string &s, std::vector<U> &output)
|
||||
{
|
||||
uint64_t sz;
|
||||
|
||||
read("", sz);
|
||||
output.resize(sz);
|
||||
for (uint64_t i = 0; i < sz; ++i)
|
||||
{
|
||||
read("", output[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
115
Grid/serialisation/Hdf5IO.cc
Normal file
115
Grid/serialisation/Hdf5IO.cc
Normal file
@ -0,0 +1,115 @@
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace Grid;
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
using namespace H5NS;
|
||||
#endif
|
||||
|
||||
// Writer implementation ///////////////////////////////////////////////////////
|
||||
Hdf5Writer::Hdf5Writer(const std::string &fileName)
|
||||
: fileName_(fileName)
|
||||
, file_(fileName.c_str(), H5F_ACC_TRUNC)
|
||||
{
|
||||
group_ = file_.openGroup("/");
|
||||
writeSingleAttribute(dataSetThres_, HDF5_GRID_GUARD "dataset_threshold",
|
||||
Hdf5Type<unsigned int>::type());
|
||||
}
|
||||
|
||||
void Hdf5Writer::push(const std::string &s)
|
||||
{
|
||||
group_ = group_.createGroup(s);
|
||||
path_.push_back(s);
|
||||
}
|
||||
|
||||
void Hdf5Writer::pop(void)
|
||||
{
|
||||
path_.pop_back();
|
||||
if (path_.empty())
|
||||
{
|
||||
group_ = file_.openGroup("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto binOp = [](const std::string &a, const std::string &b)->std::string
|
||||
{
|
||||
return a + "/" + b;
|
||||
};
|
||||
|
||||
group_ = group_.openGroup(std::accumulate(path_.begin(), path_.end(),
|
||||
std::string(""), binOp));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x)
|
||||
{
|
||||
StrType strType(PredType::C_S1, x.size());
|
||||
|
||||
writeSingleAttribute(*(x.data()), s, strType);
|
||||
}
|
||||
|
||||
void Hdf5Writer::writeDefault(const std::string &s, const char *x)
|
||||
{
|
||||
std::string sx(x);
|
||||
|
||||
writeDefault(s, sx);
|
||||
}
|
||||
|
||||
Group & Hdf5Writer::getGroup(void)
|
||||
{
|
||||
return group_;
|
||||
}
|
||||
|
||||
// Reader implementation ///////////////////////////////////////////////////////
|
||||
Hdf5Reader::Hdf5Reader(const std::string &fileName)
|
||||
: fileName_(fileName)
|
||||
, file_(fileName.c_str(), H5F_ACC_RDWR)
|
||||
{
|
||||
group_ = file_.openGroup("/");
|
||||
readSingleAttribute(dataSetThres_, HDF5_GRID_GUARD "dataset_threshold",
|
||||
Hdf5Type<unsigned int>::type());
|
||||
}
|
||||
|
||||
bool Hdf5Reader::push(const std::string &s)
|
||||
{
|
||||
group_ = group_.openGroup(s);
|
||||
path_.push_back(s);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Hdf5Reader::pop(void)
|
||||
{
|
||||
path_.pop_back();
|
||||
if (path_.empty())
|
||||
{
|
||||
group_ = file_.openGroup("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
auto binOp = [](const std::string &a, const std::string &b)->std::string
|
||||
{
|
||||
return a + "/" + b;
|
||||
};
|
||||
|
||||
group_ = group_.openGroup(std::accumulate(path_.begin(), path_.end(),
|
||||
std::string(""), binOp));
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void Hdf5Reader::readDefault(const std::string &s, std::string &x)
|
||||
{
|
||||
Attribute attribute;
|
||||
|
||||
attribute = group_.openAttribute(s);
|
||||
StrType strType = attribute.getStrType();
|
||||
|
||||
x.resize(strType.getSize());
|
||||
attribute.read(strType, &(x[0]));
|
||||
}
|
||||
|
||||
Group & Hdf5Reader::getGroup(void)
|
||||
{
|
||||
return group_;
|
||||
}
|
245
Grid/serialisation/Hdf5IO.h
Normal file
245
Grid/serialisation/Hdf5IO.h
Normal file
@ -0,0 +1,245 @@
|
||||
#ifndef GRID_SERIALISATION_HDF5_H
|
||||
#define GRID_SERIALISATION_HDF5_H
|
||||
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <H5Cpp.h>
|
||||
#include <Grid/tensors/Tensors.h>
|
||||
#include "Hdf5Type.h"
|
||||
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
#define H5NS H5
|
||||
#endif
|
||||
|
||||
// default thresold above which datasets are used instead of attributes
|
||||
#ifndef HDF5_DEF_DATASET_THRES
|
||||
#define HDF5_DEF_DATASET_THRES 6u
|
||||
#endif
|
||||
|
||||
// name guard for Grid metadata
|
||||
#define HDF5_GRID_GUARD "_Grid_"
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
class Hdf5Writer: public Writer<Hdf5Writer>
|
||||
{
|
||||
public:
|
||||
Hdf5Writer(const std::string &fileName);
|
||||
virtual ~Hdf5Writer(void) = default;
|
||||
void push(const std::string &s);
|
||||
void pop(void);
|
||||
void writeDefault(const std::string &s, const char *x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||
writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
template <typename U>
|
||||
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||
writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
H5NS::Group & getGroup(void);
|
||||
private:
|
||||
template <typename U>
|
||||
void writeSingleAttribute(const U &x, const std::string &name,
|
||||
const H5NS::DataType &type);
|
||||
private:
|
||||
std::string fileName_;
|
||||
std::vector<std::string> path_;
|
||||
H5NS::H5File file_;
|
||||
H5NS::Group group_;
|
||||
unsigned int dataSetThres_{HDF5_DEF_DATASET_THRES};
|
||||
};
|
||||
|
||||
class Hdf5Reader: public Reader<Hdf5Reader>
|
||||
{
|
||||
public:
|
||||
Hdf5Reader(const std::string &fileName);
|
||||
virtual ~Hdf5Reader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||
readDefault(const std::string &s, std::vector<U> &x);
|
||||
template <typename U>
|
||||
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||
readDefault(const std::string &s, std::vector<U> &x);
|
||||
H5NS::Group & getGroup(void);
|
||||
private:
|
||||
template <typename U>
|
||||
void readSingleAttribute(U &x, const std::string &name,
|
||||
const H5NS::DataType &type);
|
||||
private:
|
||||
std::string fileName_;
|
||||
std::vector<std::string> path_;
|
||||
H5NS::H5File file_;
|
||||
H5NS::Group group_;
|
||||
unsigned int dataSetThres_;
|
||||
};
|
||||
|
||||
// Writer template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void Hdf5Writer::writeSingleAttribute(const U &x, const std::string &name,
|
||||
const H5NS::DataType &type)
|
||||
{
|
||||
H5NS::Attribute attribute;
|
||||
hsize_t attrDim = 1;
|
||||
H5NS::DataSpace attrSpace(1, &attrDim);
|
||||
|
||||
attribute = group_.createAttribute(name, type, attrSpace);
|
||||
attribute.write(type, &x);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void Hdf5Writer::writeDefault(const std::string &s, const U &x)
|
||||
{
|
||||
writeSingleAttribute(x, s, Hdf5Type<U>::type());
|
||||
}
|
||||
|
||||
template <>
|
||||
void Hdf5Writer::writeDefault(const std::string &s, const std::string &x);
|
||||
|
||||
template <typename U>
|
||||
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
// alias to element type
|
||||
typedef typename element<std::vector<U>>::type Element;
|
||||
|
||||
// flatten the vector and getting dimensions
|
||||
Flatten<std::vector<U>> flat(x);
|
||||
std::vector<hsize_t> dim;
|
||||
const auto &flatx = flat.getFlatVector();
|
||||
|
||||
for (auto &d: flat.getDim())
|
||||
{
|
||||
dim.push_back(d);
|
||||
}
|
||||
|
||||
// write to file
|
||||
H5NS::DataSpace dataSpace(dim.size(), dim.data());
|
||||
|
||||
if (flatx.size() > dataSetThres_)
|
||||
{
|
||||
H5NS::DataSet dataSet;
|
||||
|
||||
dataSet = group_.createDataSet(s, Hdf5Type<Element>::type(), dataSpace);
|
||||
dataSet.write(flatx.data(), Hdf5Type<Element>::type());
|
||||
}
|
||||
else
|
||||
{
|
||||
H5NS::Attribute attribute;
|
||||
|
||||
attribute = group_.createAttribute(s, Hdf5Type<Element>::type(), dataSpace);
|
||||
attribute.write(Hdf5Type<Element>::type(), flatx.data());
|
||||
}
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||
Hdf5Writer::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
push(s);
|
||||
writeSingleAttribute(x.size(), HDF5_GRID_GUARD "vector_size",
|
||||
Hdf5Type<uint64_t>::type());
|
||||
for (hsize_t i = 0; i < x.size(); ++i)
|
||||
{
|
||||
write(s + "_" + std::to_string(i), x[i]);
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void Hdf5Reader::readSingleAttribute(U &x, const std::string &name,
|
||||
const H5NS::DataType &type)
|
||||
{
|
||||
H5NS::Attribute attribute;
|
||||
|
||||
attribute = group_.openAttribute(name);
|
||||
attribute.read(type, &x);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void Hdf5Reader::readDefault(const std::string &s, U &output)
|
||||
{
|
||||
readSingleAttribute(output, s, Hdf5Type<U>::type());
|
||||
}
|
||||
|
||||
template <>
|
||||
void Hdf5Reader::readDefault(const std::string &s, std::string &x);
|
||||
|
||||
template <typename U>
|
||||
typename std::enable_if<element<std::vector<U>>::is_number, void>::type
|
||||
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
|
||||
{
|
||||
// alias to element type
|
||||
typedef typename element<std::vector<U>>::type Element;
|
||||
|
||||
// read the dimensions
|
||||
H5NS::DataSpace dataSpace;
|
||||
std::vector<hsize_t> hdim;
|
||||
std::vector<size_t> dim;
|
||||
hsize_t size = 1;
|
||||
|
||||
if (group_.attrExists(s))
|
||||
{
|
||||
dataSpace = group_.openAttribute(s).getSpace();
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSpace = group_.openDataSet(s).getSpace();
|
||||
}
|
||||
hdim.resize(dataSpace.getSimpleExtentNdims());
|
||||
dataSpace.getSimpleExtentDims(hdim.data());
|
||||
for (auto &d: hdim)
|
||||
{
|
||||
dim.push_back(d);
|
||||
size *= d;
|
||||
}
|
||||
|
||||
// read the flat vector
|
||||
std::vector<Element> buf(size);
|
||||
|
||||
if (size > dataSetThres_)
|
||||
{
|
||||
H5NS::DataSet dataSet;
|
||||
|
||||
dataSet = group_.openDataSet(s);
|
||||
dataSet.read(buf.data(), Hdf5Type<Element>::type());
|
||||
}
|
||||
else
|
||||
{
|
||||
H5NS::Attribute attribute;
|
||||
|
||||
attribute = group_.openAttribute(s);
|
||||
attribute.read(Hdf5Type<Element>::type(), buf.data());
|
||||
}
|
||||
|
||||
// reconstruct the multidimensional vector
|
||||
Reconstruct<std::vector<U>> r(buf, dim);
|
||||
|
||||
x = r.getVector();
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
typename std::enable_if<!element<std::vector<U>>::is_number, void>::type
|
||||
Hdf5Reader::readDefault(const std::string &s, std::vector<U> &x)
|
||||
{
|
||||
uint64_t size;
|
||||
|
||||
push(s);
|
||||
readSingleAttribute(size, HDF5_GRID_GUARD "vector_size",
|
||||
Hdf5Type<uint64_t>::type());
|
||||
x.resize(size);
|
||||
for (hsize_t i = 0; i < x.size(); ++i)
|
||||
{
|
||||
read(s + "_" + std::to_string(i), x[i]);
|
||||
}
|
||||
pop();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
77
Grid/serialisation/Hdf5Type.h
Normal file
77
Grid/serialisation/Hdf5Type.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifndef GRID_SERIALISATION_HDF5_TYPE_H
|
||||
#define GRID_SERIALISATION_HDF5_TYPE_H
|
||||
|
||||
#include <H5Cpp.h>
|
||||
#include <complex>
|
||||
#include <memory>
|
||||
|
||||
#ifndef H5_NO_NAMESPACE
|
||||
#define H5NS H5
|
||||
#endif
|
||||
|
||||
#define HDF5_NATIVE_TYPE(predType, cType)\
|
||||
template <>\
|
||||
class Hdf5Type<cType>\
|
||||
{\
|
||||
public:\
|
||||
static inline const H5NS::DataType & type(void)\
|
||||
{\
|
||||
return H5NS::PredType::predType;\
|
||||
}\
|
||||
static constexpr bool isNative = true;\
|
||||
};
|
||||
|
||||
#define DEFINE_HDF5_NATIVE_TYPES \
|
||||
HDF5_NATIVE_TYPE(NATIVE_B8, bool);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_CHAR, char);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_SCHAR, signed char);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_UCHAR, unsigned char);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_SHORT, short);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_USHORT, unsigned short);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_INT, int);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_UINT, unsigned int);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_LONG, long);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_ULONG, unsigned long);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_LLONG, long long);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_ULLONG, unsigned long long);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_FLOAT, float);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_DOUBLE, double);\
|
||||
HDF5_NATIVE_TYPE(NATIVE_LDOUBLE, long double);
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
template <typename T> class Hdf5Type
|
||||
{
|
||||
public:
|
||||
static constexpr bool isNative = false;
|
||||
};
|
||||
|
||||
DEFINE_HDF5_NATIVE_TYPES;
|
||||
|
||||
template <typename R>
|
||||
class Hdf5Type<std::complex<R>>
|
||||
{
|
||||
public:
|
||||
static inline const H5NS::DataType & type(void)
|
||||
{
|
||||
if (typePtr_ == nullptr)
|
||||
{
|
||||
typePtr_.reset(new H5NS::CompType(sizeof(std::complex<R>)));
|
||||
typePtr_->insertMember("re", 0, Hdf5Type<R>::type());
|
||||
typePtr_->insertMember("im", sizeof(R), Hdf5Type<R>::type());
|
||||
}
|
||||
|
||||
return *typePtr_;
|
||||
}
|
||||
static constexpr bool isNative = false;
|
||||
private:
|
||||
static std::unique_ptr<H5NS::CompType> typePtr_;
|
||||
};
|
||||
|
||||
template <typename R>
|
||||
std::unique_ptr<H5NS::CompType> Hdf5Type<std::complex<R>>::typePtr_ = nullptr;
|
||||
}
|
||||
|
||||
#undef HDF5_NATIVE_TYPE
|
||||
|
||||
#endif /* GRID_SERIALISATION_HDF5_TYPE_H */
|
173
Grid/serialisation/JSON_IO.cc
Normal file
173
Grid/serialisation/JSON_IO.cc
Normal file
@ -0,0 +1,173 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/JSON_IO.cc
|
||||
|
||||
Copyright (C) 2016
|
||||
|
||||
Author: Guido Cossu<guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/Grid.h>
|
||||
|
||||
using namespace Grid;
|
||||
|
||||
// Writer implementation ///////////////////////////////////////////////////////
|
||||
JSONWriter::JSONWriter(const std::string &fileName)
|
||||
: fileName_(fileName), ss_("{ ", std::ostringstream::ate){}
|
||||
|
||||
JSONWriter::~JSONWriter(void)
|
||||
{
|
||||
// close
|
||||
delete_comma();
|
||||
ss_ << "}";
|
||||
|
||||
// write prettified JSON to file
|
||||
std::ofstream os(fileName_);
|
||||
//std::cout << "JSONWriter::~JSONWriter" << std::endl;
|
||||
os << std::setw(2) << json::parse(ss_.str()) << std::endl;
|
||||
}
|
||||
|
||||
void JSONWriter::push(const std::string &s)
|
||||
{
|
||||
// adding a nested object
|
||||
if (s.size())
|
||||
ss_ << " \""<<s<<"\" : {";
|
||||
else
|
||||
ss_ << " {";
|
||||
}
|
||||
|
||||
void JSONWriter::pop(void)
|
||||
{
|
||||
//std::cout << "JSONWriter::pop" << std::endl;
|
||||
delete_comma();
|
||||
ss_ << "},";
|
||||
}
|
||||
|
||||
void JSONWriter::delete_comma()
|
||||
{
|
||||
std::string dlast = ss_.str();
|
||||
dlast.pop_back(); // deletes the last comma
|
||||
ss_.str(dlast);
|
||||
}
|
||||
|
||||
|
||||
// here we are hitting a g++ bug (Bug 56480)
|
||||
// compiles fine with clang
|
||||
// have to wrap in the Grid namespace
|
||||
// annoying, but necessary for TravisCI
|
||||
namespace Grid
|
||||
{
|
||||
void JSONWriter::writeDefault(const std::string &s, const std::string &x)
|
||||
{
|
||||
//std::cout << "JSONWriter::writeDefault(string) : " << s << std::endl;
|
||||
std::ostringstream os;
|
||||
os << std::boolalpha << x;
|
||||
if (s.size())
|
||||
ss_ << "\""<< s << "\" : \"" << os.str() << "\" ," ;
|
||||
else
|
||||
ss_ << os.str() << " ," ;
|
||||
}
|
||||
}// namespace Grid
|
||||
|
||||
|
||||
// Reader implementation ///////////////////////////////////////////////////////
|
||||
JSONReader::JSONReader(const std::string &fileName)
|
||||
: fileName_(fileName)
|
||||
{
|
||||
std::ifstream file(fileName_);
|
||||
file >> jobject_;
|
||||
|
||||
// test
|
||||
// serialize to standard output
|
||||
//std::cout << "JSONReader::JSONReader : " << jobject_ << endl;
|
||||
jcur_ = jobject_;
|
||||
}
|
||||
|
||||
bool JSONReader::push(const std::string &s)
|
||||
{
|
||||
if (s.size()){
|
||||
jold_.push_back(jcur_);
|
||||
do_pop.push_back(true);
|
||||
try
|
||||
{
|
||||
jcur_ = jcur_[s];
|
||||
}
|
||||
catch (std::out_of_range& e)
|
||||
{
|
||||
std::cout << "out of range: " << e.what() << '\n';
|
||||
return false;
|
||||
}
|
||||
//cout << "JSONReader::push : " << s << " : "<< jcur_ << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
do_pop.push_back(false);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSONReader::pop(void)
|
||||
{
|
||||
if (do_pop.back()){
|
||||
jcur_ = jold_.back();
|
||||
jold_.pop_back();
|
||||
do_pop.pop_back();
|
||||
}
|
||||
else
|
||||
do_pop.pop_back();
|
||||
|
||||
//cout << "JSONReader::pop : " << jcur_ << endl;
|
||||
}
|
||||
|
||||
bool JSONReader::nextElement(const std::string &s)
|
||||
{
|
||||
// Work in progress
|
||||
// JSON dictionaries do not support multiple names
|
||||
// Same name objects must be packed in vectors
|
||||
++it_;
|
||||
|
||||
//if (it_ == it_end_){
|
||||
// return false;
|
||||
//}
|
||||
|
||||
jcur_ = *it_;
|
||||
//cout << "JSONReader::nextElement(string) : " << s << " : "<< jcur_ << endl;
|
||||
//return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <>
|
||||
void JSONReader::readDefault(const std::string &s, std::string &output)
|
||||
{
|
||||
//cout << "JSONReader::readDefault(string) : " << s<< " " << jcur_ << endl;
|
||||
if (s.size()){
|
||||
//std::cout << "String: "<< jcur_[s] << std::endl;
|
||||
output = jcur_[s];
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout << "String: "<< jcur_ << std::endl;
|
||||
output = jcur_;
|
||||
}
|
||||
}
|
262
Grid/serialisation/JSON_IO.h
Normal file
262
Grid/serialisation/JSON_IO.h
Normal file
@ -0,0 +1,262 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/JSON_IO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Guido Cossu<guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_JSON_IO_H
|
||||
#define GRID_SERIALISATION_JSON_IO_H
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include <Grid/json/json.hpp>
|
||||
|
||||
// for convenience
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
|
||||
class JSONWriter: public Writer<JSONWriter>
|
||||
{
|
||||
|
||||
public:
|
||||
JSONWriter(const std::string &fileName);
|
||||
virtual ~JSONWriter(void);
|
||||
void push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::complex<U> &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
template <typename U, typename P>
|
||||
void writeDefault(const std::string &s, const std::pair<U,P> &x);
|
||||
|
||||
template<std::size_t N>
|
||||
void writeDefault(const std::string &s, const char(&x)[N]);
|
||||
|
||||
void writeDefault(const std::string &s, const std::string &x);
|
||||
|
||||
|
||||
private:
|
||||
void delete_comma();
|
||||
std::string fileName_;
|
||||
std::ostringstream ss_;
|
||||
};
|
||||
|
||||
class JSONReader: public Reader<JSONReader>
|
||||
{
|
||||
public:
|
||||
JSONReader(const std::string &fileName);
|
||||
virtual ~JSONReader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
bool nextElement(const std::string &s);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::complex<U> &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::vector<U> &output);
|
||||
template <typename U, typename P>
|
||||
void readDefault(const std::string &s, std::pair<U,P> &output);
|
||||
private:
|
||||
json jobject_; // main object
|
||||
json jcur_; // current json object
|
||||
std::vector<json> jold_; // previous json object
|
||||
std::string fileName_;
|
||||
std::vector<bool> do_pop;
|
||||
json::iterator it_;
|
||||
json::iterator it_end_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct isReader< JSONReader > {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct isWriter< JSONWriter > {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// Writer template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void JSONWriter::writeDefault(const std::string &s, const U &x)
|
||||
{
|
||||
//std::cout << "JSONWriter::writeDefault(U) : " << s << " " << x <<std::endl;
|
||||
std::ostringstream os;
|
||||
os << std::boolalpha << x;
|
||||
if (s.size())
|
||||
ss_ << "\""<< s << "\" : " << os.str() << " ," ;
|
||||
else
|
||||
ss_ << os.str() << " ," ;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void JSONWriter::writeDefault(const std::string &s, const std::complex<U> &x)
|
||||
{
|
||||
//std::cout << "JSONWriter::writeDefault(complex) : " << s << " " << x << std::endl;
|
||||
std::ostringstream os;
|
||||
os << "["<< std::boolalpha << x.real() << ", " << x.imag() << "]";
|
||||
if (s.size())
|
||||
ss_ << "\""<< s << "\" : " << os.str() << " ," ;
|
||||
else
|
||||
ss_ << os.str() << " ," ;
|
||||
}
|
||||
|
||||
template <typename U, typename P>
|
||||
void JSONWriter::writeDefault(const std::string &s, const std::pair<U,P> &x)
|
||||
{
|
||||
//std::cout << "JSONWriter::writeDefault(pair) : " << s << " " << x << std::endl;
|
||||
std::ostringstream os;
|
||||
os << "["<< std::boolalpha << "\""<< x.first << "\" , \"" << x.second << "\" ]";
|
||||
if (s.size())
|
||||
ss_ << "\""<< s << "\" : " << os.str() << " ," ;
|
||||
else
|
||||
ss_ << os.str() << " ," ;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void JSONWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
//std::cout << "JSONWriter::writeDefault(vec U) : " << s << std::endl;
|
||||
|
||||
if (s.size())
|
||||
ss_ << " \""<<s<<"\" : [";
|
||||
else
|
||||
ss_ << " [";
|
||||
for (auto &x_i: x)
|
||||
{
|
||||
write("", x_i);
|
||||
}
|
||||
delete_comma();
|
||||
ss_<< "],";
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
void JSONWriter::writeDefault(const std::string &s, const char(&x)[N]){
|
||||
//std::cout << "JSONWriter::writeDefault(char U) : " << s << " " << x << std::endl;
|
||||
|
||||
if (s.size())
|
||||
ss_ << "\""<< s << "\" : \"" << x << "\" ," ;
|
||||
else
|
||||
ss_ << "\"" << x << "\" ," ;
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void JSONReader::readDefault(const std::string &s, U &output)
|
||||
{
|
||||
//std::cout << "JSONReader::readDefault(U) : " << s << " : "<< jcur_ << std::endl;
|
||||
|
||||
if (s.size()){
|
||||
//std::cout << "String: "<< jcur_[s] << std::endl;
|
||||
output = jcur_[s];
|
||||
}
|
||||
else
|
||||
{
|
||||
//std::cout << "String: "<< jcur_ << std::endl;
|
||||
output = jcur_;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U, typename P>
|
||||
void JSONReader::readDefault(const std::string &s, std::pair<U,P> &output)
|
||||
{
|
||||
U first;
|
||||
P second;
|
||||
json j;
|
||||
if (s.size()){
|
||||
//std::cout << "JSONReader::readDefault(pair) : " << s << " | "<< jcur_[s] << std::endl;
|
||||
j = jcur_[s];
|
||||
} else {
|
||||
j = jcur_;
|
||||
}
|
||||
json::iterator it = j.begin();
|
||||
jcur_ = *it;
|
||||
read("", first);
|
||||
it++;
|
||||
jcur_ = *it;
|
||||
read("", second);
|
||||
output = std::pair<U,P>(first,second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template <typename U>
|
||||
void JSONReader::readDefault(const std::string &s, std::complex<U> &output)
|
||||
{
|
||||
U tmp1, tmp2;
|
||||
//std::cout << "JSONReader::readDefault(complex U) : " << s << " : "<< jcur_ << std::endl;
|
||||
json j = jcur_;
|
||||
json::iterator it = j.begin();
|
||||
jcur_ = *it;
|
||||
read("", tmp1);
|
||||
it++;
|
||||
jcur_ = *it;
|
||||
read("", tmp2);
|
||||
output = std::complex<U>(tmp1,tmp2);
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
void JSONReader::readDefault(const std::string &s, std::string &output);
|
||||
|
||||
template <typename U>
|
||||
void JSONReader::readDefault(const std::string &s, std::vector<U> &output)
|
||||
{
|
||||
std::string buf;
|
||||
unsigned int i = 0;
|
||||
//std::cout << "JSONReader::readDefault(vec) : " << jcur_ << std::endl;
|
||||
if (s.size())
|
||||
push(s);
|
||||
|
||||
json j = jcur_;
|
||||
for (json::iterator it = j.begin(); it != j.end(); ++it) {
|
||||
jcur_ = *it;
|
||||
//std::cout << "Value: " << it.value() << "\n";
|
||||
output.resize(i + 1);
|
||||
read("", output[i++]);
|
||||
}
|
||||
|
||||
|
||||
jcur_ = j;
|
||||
if (s.size())
|
||||
pop();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
211
Grid/serialisation/MacroMagic.h
Normal file
211
Grid/serialisation/MacroMagic.h
Normal file
@ -0,0 +1,211 @@
|
||||
#ifndef GRID_MACRO_MAGIC_H
|
||||
#define GRID_MACRO_MAGIC_H
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Strong credit to :
|
||||
//
|
||||
// http://jhnet.co.uk/articles/cpp_magic
|
||||
//
|
||||
//
|
||||
// "The C Pre-Processor (CPP) is the somewhat basic macro system used by the C
|
||||
// programming language to implement features such as #include and #define
|
||||
// which allow very simple text-substitutions to be carried out at compile time.
|
||||
// In this article we abuse the humble #define to implement if-statements and iteration.
|
||||
//
|
||||
// Before we begin, a disclaimer: these tricks, while perfectly valid C, should not be
|
||||
// considered good development practice and should almost certainly not be used for "real work".
|
||||
// That said it can totally be used for fun home-automation projects...
|
||||
//
|
||||
// https://github.com/18sg/uSHET/blob/master/lib/cpp_magic.h
|
||||
//
|
||||
// The cpp_magic.h license (prior to my modifications):
|
||||
/*
|
||||
Copyright (c) 2014 Thomas Nixon, Jonathan Heathcote
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
///////////////////////////////////////////
|
||||
|
||||
#define strong_inline __attribute__((always_inline)) inline
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x,y) ((x)>(y)?(x):(y))
|
||||
#define MIN(x,y) ((x)>(y)?(y):(x))
|
||||
#endif
|
||||
|
||||
#define GRID_MACRO_FIRST(a, ...) a
|
||||
#define GRID_MACRO_SECOND(a, b, ...) b
|
||||
|
||||
#define GRID_MACRO_EMPTY()
|
||||
|
||||
#define GRID_MACRO_EVAL(...) GRID_MACRO_EVAL64(__VA_ARGS__)
|
||||
#define GRID_MACRO_EVAL1024(...) GRID_MACRO_EVAL512(GRID_MACRO_EVAL512(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL512(...) GRID_MACRO_EVAL256(GRID_MACRO_EVAL256(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL256(...) GRID_MACRO_EVAL128(GRID_MACRO_EVAL128(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL128(...) GRID_MACRO_EVAL64(GRID_MACRO_EVAL64(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL64(...) GRID_MACRO_EVAL32(GRID_MACRO_EVAL32(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL32(...) GRID_MACRO_EVAL16(GRID_MACRO_EVAL16(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL16(...) GRID_MACRO_EVAL8(GRID_MACRO_EVAL8(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL8(...) GRID_MACRO_EVAL4(GRID_MACRO_EVAL4(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL4(...) GRID_MACRO_EVAL2(GRID_MACRO_EVAL2(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL2(...) GRID_MACRO_EVAL1(GRID_MACRO_EVAL1(__VA_ARGS__))
|
||||
#define GRID_MACRO_EVAL1(...) __VA_ARGS__
|
||||
|
||||
#define GRID_MACRO_DEFER1(m) m GRID_MACRO_EMPTY()
|
||||
#define GRID_MACRO_DEFER2(m) m GRID_MACRO_EMPTY GRID_MACRO_EMPTY()()
|
||||
#define GRID_MACRO_DEFER3(m) m GRID_MACRO_EMPTY GRID_MACRO_EMPTY GRID_MACRO_EMPTY()()()
|
||||
#define GRID_MACRO_DEFER4(m) m GRID_MACRO_EMPTY GRID_MACRO_EMPTY GRID_MACRO_EMPTY GRID_MACRO_EMPTY()()()()
|
||||
|
||||
#define GRID_MACRO_IS_PROBE(...) GRID_MACRO_SECOND(__VA_ARGS__, 0)
|
||||
#define GRID_MACRO_PROBE() ~, 1
|
||||
|
||||
#define GRID_MACRO_CAT(a,b) a ## b
|
||||
|
||||
#define GRID_MACRO_NOT(x) GRID_MACRO_IS_PROBE(GRID_MACRO_CAT(_GRID_MACRO_NOT_, x))
|
||||
#define _GRID_MACRO_NOT_0 GRID_MACRO_PROBE()
|
||||
|
||||
#define GRID_MACRO_BOOL(x) GRID_MACRO_NOT(GRID_MACRO_NOT(x))
|
||||
|
||||
#define GRID_MACRO_IF_ELSE(condition) _GRID_MACRO_IF_ELSE(GRID_MACRO_BOOL(condition))
|
||||
#define _GRID_MACRO_IF_ELSE(condition) GRID_MACRO_CAT(_GRID_MACRO_IF_, condition)
|
||||
|
||||
#define _GRID_MACRO_IF_1(...) __VA_ARGS__ _GRID_MACRO_IF_1_ELSE
|
||||
#define _GRID_MACRO_IF_0(...) _GRID_MACRO_IF_0_ELSE
|
||||
|
||||
#define _GRID_MACRO_IF_1_ELSE(...)
|
||||
#define _GRID_MACRO_IF_0_ELSE(...) __VA_ARGS__
|
||||
|
||||
#define GRID_MACRO_HAS_ARGS(...) GRID_MACRO_BOOL(GRID_MACRO_FIRST(_GRID_MACRO_END_OF_ARGUMENTS_ __VA_ARGS__)())
|
||||
#define _GRID_MACRO_END_OF_ARGUMENTS_() 0
|
||||
|
||||
#define GRID_MACRO_MAP(m, first, second, ...) \
|
||||
m(first,second) \
|
||||
GRID_MACRO_IF_ELSE(GRID_MACRO_HAS_ARGS(__VA_ARGS__))( \
|
||||
GRID_MACRO_DEFER4(_GRID_MACRO_MAP)()(m, __VA_ARGS__) \
|
||||
)( \
|
||||
/* Do nothing, just terminate */ \
|
||||
)
|
||||
|
||||
#define _GRID_MACRO_MAP() GRID_MACRO_MAP
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// These are the Grid extensions to serialisation (beyond popping first AND second)
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define GRID_MACRO_MEMBER(A,B) A B;
|
||||
#define GRID_MACRO_COMP_MEMBER(A,B) result = (result and (lhs. B == rhs. B));
|
||||
#define GRID_MACRO_OS_WRITE_MEMBER(A,B) os<< #A <<" " #B << " = " << obj. B << " ; " <<std::endl;
|
||||
#define GRID_MACRO_READ_MEMBER(A,B) Grid::read(RD,#B,obj. B);
|
||||
#define GRID_MACRO_WRITE_MEMBER(A,B) Grid::write(WR,#B,obj. B);
|
||||
|
||||
#define GRID_SERIALIZABLE_CLASS_MEMBERS(cname,...)\
|
||||
std::string SerialisableClassName(void) const {return std::string(#cname);} \
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_MEMBER,__VA_ARGS__))\
|
||||
template <typename T>\
|
||||
static inline void write(Writer<T> &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 <typename T>\
|
||||
static inline void read(Reader<T> &RD,const std::string &s, cname &obj){ \
|
||||
if (!push(RD,s))\
|
||||
{\
|
||||
std::cout << Grid::GridLogWarning << "IO: Cannot open node '" << s << "'" << std::endl;\
|
||||
return;\
|
||||
};\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_READ_MEMBER,__VA_ARGS__)) \
|
||||
pop(RD);\
|
||||
}\
|
||||
friend inline std::ostream & operator << (std::ostream &os, const cname &obj ) { \
|
||||
os<<"class "<<#cname<<" {"<<std::endl;\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_OS_WRITE_MEMBER,__VA_ARGS__)) \
|
||||
os<<"}"; \
|
||||
return os;\
|
||||
}\
|
||||
friend inline bool operator==(const cname &lhs, const cname &rhs) {\
|
||||
bool result = true;\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_COMP_MEMBER,__VA_ARGS__))\
|
||||
return result;\
|
||||
}
|
||||
|
||||
#define GRID_ENUM_TYPE(obj) std::remove_reference<decltype(obj)>::type
|
||||
#define GRID_MACRO_ENUMVAL(A,B) A = B,
|
||||
#define GRID_MACRO_ENUMCASE(A,B) case GRID_ENUM_TYPE(obj)::A: Grid::write(WR,s,#A); break;
|
||||
#define GRID_MACRO_ENUMTEST(A,B) else if (buf == #A) {obj = GRID_ENUM_TYPE(obj)::A;}
|
||||
#define GRID_MACRO_ENUMCASEIO(A,B) case GRID_ENUM_TYPE(obj)::A: os << #A; break;
|
||||
|
||||
#define GRID_SERIALIZABLE_ENUM(name,undefname,...)\
|
||||
class name: public Grid::Serializable\
|
||||
{\
|
||||
public:\
|
||||
enum\
|
||||
{\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMVAL,__VA_ARGS__))\
|
||||
undefname = -1\
|
||||
};\
|
||||
public:\
|
||||
name(void): value_(undefname) {};\
|
||||
name(int value): value_(value) {};\
|
||||
template <typename T>\
|
||||
static inline void write(Grid::Writer<T> &WR,const std::string &s, const name &obj)\
|
||||
{\
|
||||
switch (obj.value_)\
|
||||
{\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASE,__VA_ARGS__))\
|
||||
default: Grid::write(WR,s,#undefname); break;\
|
||||
}\
|
||||
}\
|
||||
\
|
||||
template <typename T>\
|
||||
static inline void read(Grid::Reader<T> &RD,const std::string &s, name &obj)\
|
||||
{\
|
||||
std::string buf;\
|
||||
Grid::read(RD, s, buf);\
|
||||
if (buf == #undefname) {obj = name::undefname;}\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMTEST,__VA_ARGS__))\
|
||||
else {obj = name::undefname;}\
|
||||
}\
|
||||
inline operator int(void) const\
|
||||
{\
|
||||
return value_;\
|
||||
}\
|
||||
inline friend std::ostream & operator<<(std::ostream &os, const name &obj)\
|
||||
{\
|
||||
switch (obj) {\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMCASEIO,__VA_ARGS__))\
|
||||
default: os << #undefname; break;\
|
||||
}\
|
||||
return os;\
|
||||
}\
|
||||
inline friend std::istream & operator>>(std::istream &is, name &obj)\
|
||||
{\
|
||||
std::string buf;\
|
||||
is >> buf;\
|
||||
if (buf == #undefname) {obj = name::undefname;}\
|
||||
GRID_MACRO_EVAL(GRID_MACRO_MAP(GRID_MACRO_ENUMTEST,__VA_ARGS__))\
|
||||
else {obj = name::undefname;}\
|
||||
return is;\
|
||||
}\
|
||||
private:\
|
||||
int value_;\
|
||||
};
|
||||
|
||||
|
||||
#endif
|
57
Grid/serialisation/Serialisation.h
Normal file
57
Grid/serialisation/Serialisation.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/Serialisation.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_READER_H
|
||||
#define GRID_SERIALISATION_READER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "MacroMagic.h"
|
||||
#include "BaseIO.h"
|
||||
#include "BinaryIO.h"
|
||||
#include "TextIO.h"
|
||||
#include "XmlIO.h"
|
||||
#include "JSON_IO.h"
|
||||
|
||||
#ifdef HAVE_HDF5
|
||||
#include "Hdf5IO.h"
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Todo:
|
||||
//////////////////////////////////////////
|
||||
//#include "YamlIO.h"
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Select the default serialiser use ifdef's
|
||||
//////////////////////////////////////////
|
||||
namespace Grid {
|
||||
typedef XmlReader DefaultReader;
|
||||
typedef XmlWriter DefaultWriter;
|
||||
}
|
||||
#endif
|
105
Grid/serialisation/TextIO.cc
Normal file
105
Grid/serialisation/TextIO.cc
Normal file
@ -0,0 +1,105 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/TextIO.cc
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
Author: Guido Cossu<guido.cossu@ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/GridCore.h>
|
||||
|
||||
using namespace Grid;
|
||||
|
||||
#define GRID_TEXT_INDENT 2 //number of spaces for indentation of levels
|
||||
|
||||
|
||||
// Writer implementation ///////////////////////////////////////////////////////
|
||||
TextWriter::TextWriter(const std::string &fileName)
|
||||
: file_(fileName, std::ios::out)
|
||||
{}
|
||||
|
||||
void TextWriter::push(const std::string &s)
|
||||
{
|
||||
level_++;
|
||||
};
|
||||
|
||||
void TextWriter::pop(void)
|
||||
{
|
||||
level_--;
|
||||
};
|
||||
|
||||
void TextWriter::indent(void)
|
||||
{
|
||||
for (int i = 0; i < level_; ++i)
|
||||
for (int t = 0; t < GRID_TEXT_INDENT; t++)
|
||||
file_ << ' ';
|
||||
};
|
||||
|
||||
// Reader implementation ///////////////////////////////////////////////////////
|
||||
TextReader::TextReader(const std::string &fileName)
|
||||
{
|
||||
file_.open(fileName, std::ios::in);
|
||||
if (!file_.is_open()) {
|
||||
std::cout << GridLogMessage << "TextReader: Error opening file " << fileName << std::endl;
|
||||
exit(1);// write better error handling
|
||||
}
|
||||
}
|
||||
|
||||
bool TextReader::push(const std::string &s)
|
||||
{
|
||||
level_++;
|
||||
return true;
|
||||
};
|
||||
|
||||
void TextReader::pop(void)
|
||||
{
|
||||
level_--;
|
||||
};
|
||||
|
||||
void TextReader::checkIndent(void)
|
||||
{
|
||||
char c;
|
||||
|
||||
for (int i = 0; i < level_; ++i)
|
||||
{
|
||||
bool check = true;
|
||||
for (int t = 0; t< GRID_TEXT_INDENT; t++){
|
||||
file_.get(c);
|
||||
check = check && isspace(c);
|
||||
}
|
||||
if (!check)
|
||||
{
|
||||
std::cerr << "TextReader: mismatch on level " << level_ << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void TextReader::readDefault(const std::string &s, std::string &output)
|
||||
{
|
||||
checkIndent();
|
||||
output.clear();
|
||||
getline(file_, output);
|
||||
}
|
127
Grid/serialisation/TextIO.h
Normal file
127
Grid/serialisation/TextIO.h
Normal file
@ -0,0 +1,127 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/TextIO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_TEXT_READER_H
|
||||
#define GRID_SERIALISATION_TEXT_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
|
||||
class TextWriter: public Writer<TextWriter>
|
||||
{
|
||||
public:
|
||||
TextWriter(const std::string &fileName);
|
||||
virtual ~TextWriter(void) = default;
|
||||
void push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
private:
|
||||
void indent(void);
|
||||
private:
|
||||
std::ofstream file_;
|
||||
int level_{0};
|
||||
};
|
||||
|
||||
class TextReader: public Reader<TextReader>
|
||||
{
|
||||
public:
|
||||
TextReader(const std::string &fileName);
|
||||
virtual ~TextReader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::vector<U> &output);
|
||||
private:
|
||||
void checkIndent(void);
|
||||
private:
|
||||
std::ifstream file_;
|
||||
int level_{0};
|
||||
};
|
||||
|
||||
// Writer template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void TextWriter::writeDefault(const std::string &s, const U &x)
|
||||
{
|
||||
indent();
|
||||
file_ << std::boolalpha << x << std::endl;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void TextWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
uint64_t sz = x.size();
|
||||
|
||||
write(s, sz);
|
||||
for (uint64_t i = 0; i < sz; ++i)
|
||||
{
|
||||
write(s, x[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void TextReader::readDefault(const std::string &s, U &output)
|
||||
{
|
||||
std::string buf;
|
||||
|
||||
readDefault(s, buf);
|
||||
fromString(output, buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
void TextReader::readDefault(const std::string &s, std::string &output);
|
||||
|
||||
template <typename U>
|
||||
void TextReader::readDefault(const std::string &s, std::vector<U> &output)
|
||||
{
|
||||
uint64_t sz;
|
||||
|
||||
read("", sz);
|
||||
output.resize(sz);
|
||||
for (uint64_t i = 0; i < sz; ++i)
|
||||
{
|
||||
read("", output[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
426
Grid/serialisation/VectorUtils.h
Normal file
426
Grid/serialisation/VectorUtils.h
Normal file
@ -0,0 +1,426 @@
|
||||
#ifndef GRID_SERIALISATION_VECTORUTILS_H
|
||||
#define GRID_SERIALISATION_VECTORUTILS_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <Grid/tensors/Tensors.h>
|
||||
|
||||
namespace Grid {
|
||||
// Pair IO utilities /////////////////////////////////////////////////////////
|
||||
// helper function to parse input in the format "<obj1 obj2>"
|
||||
template <typename T1, typename T2>
|
||||
inline std::istream & operator>>(std::istream &is, std::pair<T1, T2> &buf)
|
||||
{
|
||||
T1 buf1;
|
||||
T2 buf2;
|
||||
char c;
|
||||
|
||||
// Search for "pair" delimiters.
|
||||
do
|
||||
{
|
||||
is.get(c);
|
||||
} while (c != '(' && !is.eof());
|
||||
if (c == '(')
|
||||
{
|
||||
int start = is.tellg();
|
||||
do
|
||||
{
|
||||
is.get(c);
|
||||
} while (c != ')' && !is.eof());
|
||||
if (c == ')')
|
||||
{
|
||||
int end = is.tellg();
|
||||
int psize = end - start - 1;
|
||||
|
||||
// Only read data between pair limiters.
|
||||
is.seekg(start);
|
||||
std::string tmpstr(psize, ' ');
|
||||
is.read(&tmpstr[0], psize);
|
||||
std::istringstream temp(tmpstr);
|
||||
temp >> buf1 >> buf2;
|
||||
buf = std::make_pair(buf1, buf2);
|
||||
is.seekg(end);
|
||||
}
|
||||
}
|
||||
is.peek();
|
||||
return is;
|
||||
}
|
||||
|
||||
// output to streams for pairs
|
||||
template <class T1, class T2>
|
||||
inline std::ostream & operator<<(std::ostream &os, const std::pair<T1, T2> &p)
|
||||
{
|
||||
os << "(" << p.first << " " << p.second << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
// Grid scalar tensors to nested std::vectors //////////////////////////////////
|
||||
template <typename T>
|
||||
struct TensorToVec
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct TensorToVec<iScalar<T>>
|
||||
{
|
||||
typedef typename TensorToVec<T>::type type;
|
||||
};
|
||||
|
||||
template <typename T, int N>
|
||||
struct TensorToVec<iVector<T, N>>
|
||||
{
|
||||
typedef typename std::vector<typename TensorToVec<T>::type> type;
|
||||
};
|
||||
|
||||
template <typename T, int N>
|
||||
struct TensorToVec<iMatrix<T, N>>
|
||||
{
|
||||
typedef typename std::vector<std::vector<typename TensorToVec<T>::type>> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void tensorDim(std::vector<size_t> &dim, const T &t, const bool wipe = true)
|
||||
{
|
||||
if (wipe)
|
||||
{
|
||||
dim.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void tensorDim(std::vector<size_t> &dim, const iScalar<T> &t, const bool wipe = true)
|
||||
{
|
||||
if (wipe)
|
||||
{
|
||||
dim.clear();
|
||||
}
|
||||
tensorDim(dim, t._internal, false);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void tensorDim(std::vector<size_t> &dim, const iVector<T, N> &t, const bool wipe = true)
|
||||
{
|
||||
if (wipe)
|
||||
{
|
||||
dim.clear();
|
||||
}
|
||||
dim.push_back(N);
|
||||
tensorDim(dim, t._internal[0], false);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void tensorDim(std::vector<size_t> &dim, const iMatrix<T, N> &t, const bool wipe = true)
|
||||
{
|
||||
if (wipe)
|
||||
{
|
||||
dim.clear();
|
||||
}
|
||||
dim.push_back(N);
|
||||
dim.push_back(N);
|
||||
tensorDim(dim, t._internal[0][0], false);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TensorToVec<T>::type tensorToVec(const T &t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TensorToVec<iScalar<T>>::type tensorToVec(const iScalar<T>& t)
|
||||
{
|
||||
return tensorToVec(t._internal);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
typename TensorToVec<iVector<T, N>>::type tensorToVec(const iVector<T, N>& t)
|
||||
{
|
||||
typename TensorToVec<iVector<T, N>>::type v;
|
||||
|
||||
v.resize(N);
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
{
|
||||
v[i] = tensorToVec(t._internal[i]);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
typename TensorToVec<iMatrix<T, N>>::type tensorToVec(const iMatrix<T, N>& t)
|
||||
{
|
||||
typename TensorToVec<iMatrix<T, N>>::type v;
|
||||
|
||||
v.resize(N);
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
{
|
||||
v[i].resize(N);
|
||||
for (unsigned int j = 0; j < N; j++)
|
||||
{
|
||||
v[i][j] = tensorToVec(t._internal[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void vecToTensor(T &t, const typename TensorToVec<T>::type &v)
|
||||
{
|
||||
t = v;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
void vecToTensor(iScalar<T> &t, const typename TensorToVec<iScalar<T>>::type &v)
|
||||
{
|
||||
vecToTensor(t._internal, v);
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void vecToTensor(iVector<T, N> &t, const typename TensorToVec<iVector<T, N>>::type &v)
|
||||
{
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
{
|
||||
vecToTensor(t._internal[i], v[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, int N>
|
||||
void vecToTensor(iMatrix<T, N> &t, const typename TensorToVec<iMatrix<T, N>>::type &v)
|
||||
{
|
||||
for (unsigned int i = 0; i < N; i++)
|
||||
for (unsigned int j = 0; j < N; j++)
|
||||
{
|
||||
vecToTensor(t._internal[i][j], v[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
// Vector element trait //////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct element
|
||||
{
|
||||
typedef T type;
|
||||
static constexpr bool is_number = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct element<std::vector<T>>
|
||||
{
|
||||
typedef typename element<T>::type type;
|
||||
static constexpr bool is_number = std::is_arithmetic<T>::value
|
||||
or is_complex<T>::value
|
||||
or element<T>::is_number;
|
||||
};
|
||||
|
||||
// Vector flattening utility class ////////////////////////////////////////////
|
||||
// Class to flatten a multidimensional std::vector
|
||||
template <typename V>
|
||||
class Flatten
|
||||
{
|
||||
public:
|
||||
typedef typename element<V>::type Element;
|
||||
public:
|
||||
explicit Flatten(const V &vector);
|
||||
const V & getVector(void);
|
||||
const std::vector<Element> & getFlatVector(void);
|
||||
const std::vector<size_t> & getDim(void);
|
||||
private:
|
||||
void accumulate(const Element &e);
|
||||
template <typename W>
|
||||
void accumulate(const W &v);
|
||||
void accumulateDim(const Element &e);
|
||||
template <typename W>
|
||||
void accumulateDim(const W &v);
|
||||
private:
|
||||
const V &vector_;
|
||||
std::vector<Element> flatVector_;
|
||||
std::vector<size_t> dim_;
|
||||
};
|
||||
|
||||
// Class to reconstruct a multidimensional std::vector
|
||||
template <typename V>
|
||||
class Reconstruct
|
||||
{
|
||||
public:
|
||||
typedef typename element<V>::type Element;
|
||||
public:
|
||||
Reconstruct(const std::vector<Element> &flatVector,
|
||||
const std::vector<size_t> &dim);
|
||||
const V & getVector(void);
|
||||
const std::vector<Element> & getFlatVector(void);
|
||||
const std::vector<size_t> & getDim(void);
|
||||
private:
|
||||
void fill(std::vector<Element> &v);
|
||||
template <typename W>
|
||||
void fill(W &v);
|
||||
void resize(std::vector<Element> &v, const unsigned int dim);
|
||||
template <typename W>
|
||||
void resize(W &v, const unsigned int dim);
|
||||
private:
|
||||
V vector_;
|
||||
const std::vector<Element> &flatVector_;
|
||||
std::vector<size_t> dim_;
|
||||
size_t ind_{0};
|
||||
unsigned int dimInd_{0};
|
||||
};
|
||||
|
||||
// Flatten class template implementation
|
||||
template <typename V>
|
||||
void Flatten<V>::accumulate(const Element &e)
|
||||
{
|
||||
flatVector_.push_back(e);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
template <typename W>
|
||||
void Flatten<V>::accumulate(const W &v)
|
||||
{
|
||||
for (auto &e: v)
|
||||
{
|
||||
accumulate(e);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
void Flatten<V>::accumulateDim(const Element &e) {};
|
||||
|
||||
template <typename V>
|
||||
template <typename W>
|
||||
void Flatten<V>::accumulateDim(const W &v)
|
||||
{
|
||||
dim_.push_back(v.size());
|
||||
accumulateDim(v[0]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
Flatten<V>::Flatten(const V &vector)
|
||||
: vector_(vector)
|
||||
{
|
||||
accumulate(vector_);
|
||||
accumulateDim(vector_);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const V & Flatten<V>::getVector(void)
|
||||
{
|
||||
return vector_;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const std::vector<typename Flatten<V>::Element> &
|
||||
Flatten<V>::getFlatVector(void)
|
||||
{
|
||||
return flatVector_;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const std::vector<size_t> & Flatten<V>::getDim(void)
|
||||
{
|
||||
return dim_;
|
||||
}
|
||||
|
||||
// Reconstruct class template implementation
|
||||
template <typename V>
|
||||
void Reconstruct<V>::fill(std::vector<Element> &v)
|
||||
{
|
||||
for (auto &e: v)
|
||||
{
|
||||
e = flatVector_[ind_++];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
template <typename W>
|
||||
void Reconstruct<V>::fill(W &v)
|
||||
{
|
||||
for (auto &e: v)
|
||||
{
|
||||
fill(e);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
void Reconstruct<V>::resize(std::vector<Element> &v, const unsigned int dim)
|
||||
{
|
||||
v.resize(dim_[dim]);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
template <typename W>
|
||||
void Reconstruct<V>::resize(W &v, const unsigned int dim)
|
||||
{
|
||||
v.resize(dim_[dim]);
|
||||
for (auto &e: v)
|
||||
{
|
||||
resize(e, dim + 1);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
Reconstruct<V>::Reconstruct(const std::vector<Element> &flatVector,
|
||||
const std::vector<size_t> &dim)
|
||||
: flatVector_(flatVector)
|
||||
, dim_(dim)
|
||||
{
|
||||
resize(vector_, 0);
|
||||
fill(vector_);
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const V & Reconstruct<V>::getVector(void)
|
||||
{
|
||||
return vector_;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const std::vector<typename Reconstruct<V>::Element> &
|
||||
Reconstruct<V>::getFlatVector(void)
|
||||
{
|
||||
return flatVector_;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
const std::vector<size_t> & Reconstruct<V>::getDim(void)
|
||||
{
|
||||
return dim_;
|
||||
}
|
||||
|
||||
// Vector IO utilities ///////////////////////////////////////////////////////
|
||||
// helper function to read space-separated values
|
||||
template <typename T>
|
||||
std::vector<T> strToVec(const std::string s)
|
||||
{
|
||||
std::istringstream sstr(s);
|
||||
T buf;
|
||||
std::vector<T> v;
|
||||
|
||||
while(!sstr.eof())
|
||||
{
|
||||
sstr >> buf;
|
||||
v.push_back(buf);
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
// output to streams for vectors
|
||||
template < class T >
|
||||
inline std::ostream & operator<<(std::ostream &os, const std::vector<T> &v)
|
||||
{
|
||||
os << "[";
|
||||
for (unsigned int i = 0; i < v.size(); ++i)
|
||||
{
|
||||
os << v[i];
|
||||
if (i < v.size() - 1)
|
||||
{
|
||||
os << " ";
|
||||
}
|
||||
}
|
||||
os << "]";
|
||||
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
171
Grid/serialisation/XmlIO.cc
Normal file
171
Grid/serialisation/XmlIO.cc
Normal file
@ -0,0 +1,171 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/XmlIO.cc
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#include <Grid/GridCore.h>
|
||||
|
||||
using namespace Grid;
|
||||
|
||||
void Grid::xmlCheckParse(const pugi::xml_parse_result &result, const std::string name)
|
||||
{
|
||||
if (!result)
|
||||
{
|
||||
std::cerr << "XML parsing error for " << name << std::endl;
|
||||
std::cerr << "XML error description: " << result.description() << std::endl;
|
||||
std::cerr << "XML error offset : " << result.offset << std::endl;
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// Writer implementation ///////////////////////////////////////////////////////
|
||||
XmlWriter::XmlWriter(const std::string &fileName, std::string toplev) : fileName_(fileName)
|
||||
{
|
||||
if ( toplev == std::string("") ) {
|
||||
node_=doc_;
|
||||
} else {
|
||||
node_=doc_.append_child();
|
||||
node_.set_name(toplev.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
XmlWriter::~XmlWriter(void)
|
||||
{
|
||||
if ( fileName_ != std::string("") ) {
|
||||
doc_.save_file(fileName_.c_str(), indent_.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void XmlWriter::push(const std::string &s)
|
||||
{
|
||||
node_ = node_.append_child(s.c_str());
|
||||
}
|
||||
|
||||
void XmlWriter::pushXmlString(const std::string &s)
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
auto result = doc.load_buffer(s.c_str(), s.size());
|
||||
|
||||
xmlCheckParse(result, "fragment\n'" + s +"'");
|
||||
for (pugi::xml_node child = doc.first_child(); child; child = child.next_sibling())
|
||||
{
|
||||
node_ = node_.append_copy(child);
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
void XmlWriter::pop(void)
|
||||
{
|
||||
node_ = node_.parent();
|
||||
}
|
||||
|
||||
std::string XmlWriter::docString(void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
doc_.save(oss, indent_.c_str());
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string XmlWriter::string(void)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
doc_.save(oss, indent_.c_str(), pugi::format_default | pugi::format_no_declaration);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// Reader implementation ///////////////////////////////////////////////////////
|
||||
XmlReader::XmlReader(const std::string &s, const bool isBuffer,
|
||||
std::string toplev)
|
||||
{
|
||||
pugi::xml_parse_result result;
|
||||
|
||||
if (isBuffer)
|
||||
{
|
||||
fileName_ = "<string>";
|
||||
result = doc_.load_string(s.c_str());
|
||||
xmlCheckParse(result, "string\n'" + s + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
fileName_ = s;
|
||||
result = doc_.load_file(s.c_str());
|
||||
xmlCheckParse(result, "file '" + fileName_ + "'");
|
||||
}
|
||||
if ( toplev == std::string("") ) {
|
||||
node_ = doc_;
|
||||
} else {
|
||||
node_ = doc_.child(toplev.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool XmlReader::push(const std::string &s)
|
||||
{
|
||||
if (node_.child(s.c_str()))
|
||||
{
|
||||
node_ = node_.child(s.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void XmlReader::pop(void)
|
||||
{
|
||||
node_ = node_.parent();
|
||||
}
|
||||
|
||||
bool XmlReader::nextElement(const std::string &s)
|
||||
{
|
||||
if (node_.next_sibling(s.c_str()))
|
||||
{
|
||||
node_ = node_.next_sibling(s.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void XmlReader::readDefault(const std::string &s, std::string &output)
|
||||
{
|
||||
if (node_.child(s.c_str()))
|
||||
{
|
||||
output = node_.child(s.c_str()).first_child().value();
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
|
||||
std::cout << std::endl;
|
||||
|
||||
output = "";
|
||||
}
|
||||
}
|
167
Grid/serialisation/XmlIO.h
Normal file
167
Grid/serialisation/XmlIO.h
Normal file
@ -0,0 +1,167 @@
|
||||
/*************************************************************************************
|
||||
|
||||
Grid physics library, www.github.com/paboyle/Grid
|
||||
|
||||
Source file: ./lib/serialisation/XmlIO.h
|
||||
|
||||
Copyright (C) 2015
|
||||
|
||||
Author: Antonin Portelli <antonin.portelli@me.com>
|
||||
Author: Peter Boyle <paboyle@ph.ed.ac.uk>
|
||||
Author: paboyle <paboyle@ph.ed.ac.uk>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
See the full license in the file "LICENSE" in the top level distribution directory
|
||||
*************************************************************************************/
|
||||
/* END LEGAL */
|
||||
#ifndef GRID_SERIALISATION_XML_READER_H
|
||||
#define GRID_SERIALISATION_XML_READER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <math.h>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
|
||||
#include <Grid/pugixml/pugixml.h>
|
||||
#include <Grid/GridCore.h>
|
||||
|
||||
namespace Grid
|
||||
{
|
||||
void xmlCheckParse(const pugi::xml_parse_result &result, const std::string name);
|
||||
|
||||
class XmlWriter: public Writer<XmlWriter>
|
||||
{
|
||||
public:
|
||||
XmlWriter(const std::string &fileName, std::string toplev = std::string("grid") );
|
||||
virtual ~XmlWriter(void);
|
||||
void push(const std::string &s);
|
||||
void pushXmlString(const std::string &s);
|
||||
void pop(void);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const U &x);
|
||||
template <typename U>
|
||||
void writeDefault(const std::string &s, const std::vector<U> &x);
|
||||
std::string docString(void);
|
||||
std::string string(void);
|
||||
private:
|
||||
const std::string indent_{" "};
|
||||
pugi::xml_document doc_;
|
||||
pugi::xml_node node_;
|
||||
std::string fileName_;
|
||||
};
|
||||
|
||||
class XmlReader: public Reader<XmlReader>
|
||||
{
|
||||
public:
|
||||
XmlReader(const std::string &fileName, const bool isBuffer = false,
|
||||
std::string toplev = std::string("grid") );
|
||||
virtual ~XmlReader(void) = default;
|
||||
bool push(const std::string &s);
|
||||
void pop(void);
|
||||
bool nextElement(const std::string &s);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, U &output);
|
||||
template <typename U>
|
||||
void readDefault(const std::string &s, std::vector<U> &output);
|
||||
private:
|
||||
void checkParse(const pugi::xml_parse_result &result, const std::string name);
|
||||
private:
|
||||
pugi::xml_document doc_;
|
||||
pugi::xml_node node_;
|
||||
std::string fileName_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct isReader< XmlReader > {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct isWriter<XmlWriter > {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
// Writer template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void XmlWriter::writeDefault(const std::string &s, const U &x)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
if (getPrecision())
|
||||
{
|
||||
os.precision(getPrecision());
|
||||
}
|
||||
if (isScientific())
|
||||
{
|
||||
os << std::scientific;
|
||||
}
|
||||
os << std::boolalpha << x;
|
||||
pugi::xml_node leaf = node_.append_child(s.c_str());
|
||||
leaf.append_child(pugi::node_pcdata).set_value(os.str().c_str());
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
void XmlWriter::writeDefault(const std::string &s, const std::vector<U> &x)
|
||||
{
|
||||
push(s);
|
||||
for (auto &x_i: x)
|
||||
{
|
||||
write("elem", x_i);
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
// Reader template implementation ////////////////////////////////////////////
|
||||
template <typename U>
|
||||
void XmlReader::readDefault(const std::string &s, U &output)
|
||||
{
|
||||
std::string buf;
|
||||
|
||||
readDefault(s, buf);
|
||||
fromString(output, buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
void XmlReader::readDefault(const std::string &s, std::string &output);
|
||||
|
||||
template <typename U>
|
||||
void XmlReader::readDefault(const std::string &s, std::vector<U> &output)
|
||||
{
|
||||
std::string buf;
|
||||
unsigned int i = 0;
|
||||
|
||||
if (!push(s))
|
||||
{
|
||||
std::cout << GridLogWarning << "XML: cannot open node '" << s << "'";
|
||||
std::cout << std::endl;
|
||||
|
||||
return;
|
||||
}
|
||||
while (node_.child("elem"))
|
||||
{
|
||||
output.resize(i + 1);
|
||||
read("elem", output[i]);
|
||||
node_.child("elem").set_name("elem-done");
|
||||
i++;
|
||||
}
|
||||
pop();
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user