finish first version of cereal extension (more or less tested)

This commit is contained in:
Christian Zimmermann 2023-02-28 17:50:56 +01:00
parent 80ac604089
commit e016059ad0
11 changed files with 389 additions and 20 deletions

View file

@ -39,11 +39,11 @@
#define IS_NOT_SAME(a,b) (not std::is_same<a,b>::value)
#ifdef HAVE_CEREAL
#define SERIALIZATION_FUNCTIONS template <class Archive> void save(Archive& ar) const; \
template <class Archive> void load(Archive& ar)
#define SERIALIZATION_FUNCTIONS template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
template <class Archive> void load(Archive& ar, const std::uint32_t version)
#define SERIALIZATION_FUNCTIONS_NOPUB friend class cereal::access; \
template <class Archive> void save(Archive& ar) const; \
template <class Archive> void load(Archive& ar)
template <class Archive> void save(Archive& ar, const std::uint32_t version) const; \
template <class Archive> void load(Archive& ar, const std::uint32_t version)
#else
#define SERIALIZATION_FUNCTIONS
#define SERIALIZATION_FUNCTIONS_NOPUB

View file

@ -10,17 +10,19 @@ namespace CNORXZ
{
template <typename T>
template <class Archive>
void MArray<T>::save(Archive& ar) const
void MArray<T>::save(Archive& ar, const std::uint32_t version) const
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("range", AB::mRange));
ar(cereal::make_nvp("data", mCont));
}
template <typename T>
template <class Archive>
void MArray<T>::load(Archive& ar)
void MArray<T>::load(Archive& ar, const std::uint32_t version)
{
save_load("range", AB::mRange);
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
cer::save_load(ar, "range", AB::mRange);
//ar(cereal::make_nvp("range", AB::mRange));
ar(cereal::make_nvp("data", mCont));
}

View file

@ -0,0 +1,24 @@
#ifndef __cxz_cer_base_h__
#define __cxz_cer_base_h__
#define CXZ_CEREAL_FORMAT_VERION 1u
namespace CNORXZ
{
namespace cer
{
enum class Format {
BINARY = 1u,
JSON = 2u,
XML = 3u
};
enum class ContentType {
ARRAY = 1u,
MAP = 2u
};
}
}
#endif

View file

@ -0,0 +1,34 @@
#ifndef __cxz_cereal_header_cc_h__
#define __cxz_cereal_header_cc_h__
#include "cer_header.h"
namespace CNORXZ
{
namespace cer
{
template <class Archive>
void save(Archive& ar, const Header& h, const std::uint32_t version)
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("version",h.version));
ar(cereal::make_nvp("commit",h.commit));
ar(cereal::make_nvp("content",static_cast<SizeT>(h.content)));
}
template <class Archive>
void load(Archive& ar, Header& h, const std::uint32_t version)
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("version",h.version));
ar(cereal::make_nvp("commit",h.commit));
SizeT hc;
ar(cereal::make_nvp("content",hc));
h.content = static_cast<ContentType>(hc);
}
}
}
#endif

View file

@ -0,0 +1,37 @@
#ifndef __cxz_cereal_header_h__
#define __cxz_cereal_header_h__
#include "base/base.h"
#include "cer_base.h"
namespace CNORXZ
{
namespace cer
{
struct Header
{
String version;
String commit;
ContentType content;
};
inline Header mkHeader(const ContentType content)
{
Header o;
o.version = CNORXZ::Config::version();
o.commit = CNORXZ::Config::commit();
o.content = content;
return o;
}
template <class Archive>
void save(Archive& ar, const Header& h, const std::uint32_t version);
template <class Archive>
void load(Archive& ar, Header& h, const std::uint32_t version);
}
}
#endif

View file

@ -24,8 +24,9 @@ namespace CNORXZ
}
template <class Archive>
void CRange::save(Archive& ar) const
void CRange::save(Archive& ar, const std::uint32_t version) const
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("size", mSize));
@ -33,16 +34,18 @@ namespace CNORXZ
template <class MetaT>
template <class Archive>
void URange<MetaT>::save(Archive& ar) const
void URange<MetaT>::save(Archive& ar, const std::uint32_t version) const
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("meta", mSpace));
}
template <class Archive>
void YRange::save(Archive& ar) const
void YRange::save(Archive& ar, const std::uint32_t version) const
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("sub", mRVec));
@ -60,8 +63,9 @@ namespace CNORXZ
}
template <class Archive>
void CRange::load(Archive& ar)
void CRange::load(Archive& ar, const std::uint32_t version)
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("size", mSize));
@ -70,8 +74,9 @@ namespace CNORXZ
template <class MetaT>
template <class Archive>
void URange<MetaT>::load(Archive& ar)
void URange<MetaT>::load(Archive& ar, const std::uint32_t version)
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("meta", mSpace));
@ -79,8 +84,9 @@ namespace CNORXZ
}
template <class Archive>
void YRange::load(Archive& ar)
void YRange::load(Archive& ar, const std::uint32_t version)
{
CXZ_ASSERT(version == 1u, "format version = " << version << " not supported");
ar(cereal::make_nvp("uuid", RB::mId));
ar(cereal::make_nvp("this", RB::mThis));
ar(cereal::make_nvp("sub", mRVec));

View file

@ -2,37 +2,79 @@
#ifndef __cxz_cereal_type_register_cc_h__
#define __cxz_cereal_type_register_cc_h__
#include "cer_base.h"
#include "cer_header.h"
#include "cer_ranges.cc.h"
#include "cer_array.cc.h"
#include <cereal/types/polymorphic.hpp>
CEREAL_CLASS_VERSION(CNORXZ::Uuid, CXZ_CEREAL_FORMAT_VERION);
CEREAL_CLASS_VERSION(CNORXZ::cer::Header, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::CRange);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::CRange);
CEREAL_CLASS_VERSION(CNORXZ::CRange, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::SizeT>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::SizeT>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::SizeT>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Int>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Int>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Int>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Double>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Double>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Double>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::String>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::String>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::String>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::SizeT>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::SizeT>>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Vector<CNORXZ::SizeT>>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Int>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::Int>>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Int>>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Double>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::Double>>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Vector<CNORXZ::Double>>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::URange<CNORXZ::Vector<CNORXZ::String>>);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::URange<CNORXZ::Vector<CNORXZ::String>>);
CEREAL_CLASS_VERSION(CNORXZ::URange<CNORXZ::Vector<CNORXZ::String>>, CXZ_CEREAL_FORMAT_VERION);
CEREAL_REGISTER_TYPE(CNORXZ::YRange);
CEREAL_REGISTER_POLYMORPHIC_RELATION(CNORXZ::RangeBase, CNORXZ::YRange);
CEREAL_CLASS_VERSION(CNORXZ::YRange, CXZ_CEREAL_FORMAT_VERION);
namespace cereal
{
namespace detail
{
template <typename T>
struct Version<CNORXZ::MArray<T>>
{
static const std::uint32_t version;
static std::uint32_t registerVersion()
{
::cereal::detail::StaticObject<Versions>::getInstance().mapping.emplace
( std::type_index(typeid(CNORXZ::MArray<T>)).hash_code(), CXZ_CEREAL_FORMAT_VERION );
return 3;
}
static void unused() { (void)version; }
};
template <typename T>
const std::uint32_t Version<CNORXZ::MArray<T>>::version =
Version<CNORXZ::MArray<T>>::registerVersion();
}
}
#endif

View file

@ -1,6 +1,12 @@
#include "cer_base.h"
#include "cer_header.h"
#include "range_save_load.h"
#include "utilities.h"
#include "range_save_load.cc.h"
#include "cer_array.cc.h"
#include "cer_ranges.cc.h"
#include "cer_header.cc.h"
#include "cer_type_register.cc.h"
#include "utilities.cc.h"

View file

@ -0,0 +1,58 @@
#ifndef __cxz_cereal_utilities_cc_h__
#define __cxz_cereal_utilities_cc_h__
#include <fstream>
#include "utilities.h"
#include "cer_header.h"
namespace CNORXZ
{
namespace cer
{
template <Format F, typename T>
void write(std::ostream& os, const MArray<T>& data)
{
typedef typename OutputFormatMap<F>::type OArchive;
OArchive ar(os);
auto h = mkHeader(ContentType::ARRAY);
ar(cereal::make_nvp("cnorxz",h));
ar(cereal::make_nvp("array",data));
}
template <Format F, typename T>
void read(std::istream& is, MArray<T>& data)
{
typedef typename InputFormatMap<F>::type IArchive;
IArchive ar(is);
Header h;
ar(cereal::make_nvp("cnorxz",h));
CXZ_ASSERT(h.content == ContentType::ARRAY, "expected Array (type = "
<< static_cast<SizeT>(ContentType::ARRAY) << "), got "
<< static_cast<SizeT>(h.content));
ar(cereal::make_nvp("array",data));
}
template <Format F, typename T>
void writeFile(const String& name, const MArray<T>& data)
{
std::fstream os(name, std::ios::binary | std::ios::out);
write<F>(os, data);
os.close();
}
template <Format F, typename T>
void readFile(const String& name, MArray<T>& data)
{
std::fstream is(name, std::ios::binary | std::ios::in);
read<F>(is, data);
is.close();
}
}
}
#endif

View file

@ -0,0 +1,64 @@
#ifndef __cxz_cereal_utilities_h__
#define __cxz_cereal_utilities_h__
#include <istream>
#include <ostream>
#include "base/base.h"
#include "cer_base.h"
#include <cereal/archives/xml.hpp>
#include <cereal/archives/json.hpp>
#include <cereal/archives/binary.hpp>
namespace CNORXZ
{
namespace cer
{
template <Format F>
struct OutputFormatMap
{};
template <>
struct OutputFormatMap<Format::BINARY>
{ typedef cereal::BinaryOutputArchive type; };
template <>
struct OutputFormatMap<Format::JSON>
{ typedef cereal::JSONOutputArchive type; };
template <>
struct OutputFormatMap<Format::XML>
{ typedef cereal::XMLOutputArchive type; };
template <Format F>
struct InputFormatMap
{};
template <>
struct InputFormatMap<Format::BINARY>
{ typedef cereal::BinaryInputArchive type; };
template <>
struct InputFormatMap<Format::JSON>
{ typedef cereal::JSONInputArchive type; };
template <>
struct InputFormatMap<Format::XML>
{ typedef cereal::XMLInputArchive type; };
template <Format F, typename T>
void write(std::ostream& os, const MArray<T>& data);
template <Format F, typename T>
void read(std::istream& is, MArray<T>& data);
template <Format F, typename T>
void writeFile(const String& name, const MArray<T>& data);
template <Format F, typename T>
void readFile(const String& name, MArray<T>& data);
}
}
#endif

View file

@ -8,6 +8,7 @@
#include "cnorxz.h"
#include "cnorxz_cereal.h"
#include <cereal/archives/json.hpp>
#include <cereal/archives/binary.hpp>
namespace
{
@ -65,13 +66,40 @@ namespace
std::stringstream mS2;
};
class CerMArray_Test : public ::testing::Test
{
protected:
CerMArray_Test()
{
mSize = 7;
mMeta = { "some", "random", "words", "with", "no", "meaning" };
mR1 = CRangeFactory(mSize).create();
mR2 = URangeFactory(mMeta).create();
mR = YRangeFactory({mR1,mR2}).create();
mData.resize(mR->size());
for(SizeT i = 0; i != mData.size(); ++i){
mData[i] = static_cast<Double>(i)/static_cast<Double>(mData.size());
}
mArr = MArray(mR, mData);
}
SizeT mSize;
Vector<String> mMeta;
RangePtr mR1;
RangePtr mR2;
RangePtr mR;
Vector<Double> mData;
MArray<Double> mArr;
std::stringstream mS;
};
TEST_F(CerCRange_Test, Serialize)
{
{
cereal::JSONOutputArchive ar(mS);
ar(mR);
}
std::cout << mS.str() << std::endl;
RangePtr r = nullptr;
{
cereal::JSONInputArchive ar(mS);
@ -94,7 +122,6 @@ namespace
cereal::JSONOutputArchive ar(mS);
ar(mR);
}
std::cout << mS.str() << std::endl;
RangePtr r = nullptr;
{
cereal::JSONInputArchive ar(mS);
@ -116,9 +143,7 @@ namespace
{
cereal::JSONOutputArchive ar(mS);
ar(cereal::make_nvp("mR",mR));
//ar(mR);
}
std::cout << mS.str() << std::endl;
RangePtr r = nullptr;
{
cereal::JSONInputArchive ar(mS);
@ -135,6 +160,28 @@ namespace
}
}
TEST_F(CerYRange_Test, Binary)
{
{
cereal::BinaryOutputArchive ar(mS);
ar(cereal::make_nvp("mR",mR));
}
RangePtr r = nullptr;
{
cereal::BinaryInputArchive ar(mS);
cer::save_load(ar, "mR", r);
}
EXPECT_EQ(r->size(), mR->size());
EXPECT_EQ(r->dim(), mR->dim());
auto i1 = r->begin();
auto i2 = mR->begin();
auto i1e = r->end();
auto i2e = mR->end();
for(; i1 != i1e; ++i1, ++i2){
EXPECT_TRUE(*i1 == *i2);
}
}
TEST_F(CerYRange_Test, NoDuplicates)
{
{
@ -145,17 +192,14 @@ namespace
cereal::JSONOutputArchive ar(mS2);
ar(cereal::make_nvp("mR",mR));
}
std::cout << mS.str() << std::endl;
RangePtr r = nullptr;
{
cereal::JSONInputArchive ar(mS);
//ar(r);
cer::save_load(ar, "mR", r);
}
RangePtr r2 = nullptr;
{
cereal::JSONInputArchive ar(mS2);
//ar(r2);
cer::save_load(ar, "mR", r2);
}
@ -173,6 +217,58 @@ namespace
EXPECT_TRUE(*i1 == *i2);
}
}
TEST_F(CerMArray_Test, ToStream)
{
cer::write<cer::Format::JSON>(mS, mArr);
//std::cout << mS.str() << std::endl;
MArray<Double> arr;
cer::read<cer::Format::JSON>(mS, arr);
auto i1 = mArr.begin();
auto i2 = arr.begin();
auto i1e = mArr.end();
auto i2e = arr.end();
for(; i1 != i1e; ++i1, ++i2){
EXPECT_TRUE(i1.meta() == i2.meta());
EXPECT_EQ(*i1, *i2);
}
}
TEST_F(CerMArray_Test, ToTxtFile)
{
cer::writeFile<cer::Format::JSON>("cxzcer.testfile.json", mArr);
MArray<Double> arr;
cer::readFile<cer::Format::JSON>("cxzcer.testfile.json", arr);
auto i1 = mArr.begin();
auto i2 = arr.begin();
auto i1e = mArr.end();
auto i2e = arr.end();
for(; i1 != i1e; ++i1, ++i2){
EXPECT_TRUE(i1.meta() == i2.meta());
EXPECT_EQ(*i1, *i2);
}
}
TEST_F(CerMArray_Test, ToBinaryFile)
{
cer::writeFile<cer::Format::BINARY>("cxzcer.testfile.bin", mArr);
MArray<Double> arr;
cer::readFile<cer::Format::BINARY>("cxzcer.testfile.bin", arr);
auto i1 = mArr.begin();
auto i2 = arr.begin();
auto i1e = mArr.end();
auto i2e = arr.end();
for(; i1 != i1e; ++i1, ++i2){
EXPECT_TRUE(i1.meta() == i2.meta());
EXPECT_EQ(*i1, *i2);
}
}
}
int main(int argc, char** argv)