ArchiveCollection.h
// ArchiveCollection.h
//
// Author David Barrett-Lennard
// (C)opyright Cedanet Pty Ltd 2019
#pragma once
#include "CedaAssert.h"
#include "VariableLengthSerialise.h"
#include "Archive.h"
#include "xdeque.h"
#include "xvector.h"
#include <array>
#include <deque>
#include <forward_list>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <string.h>
namespace ceda
{
template<typename T, typename Archive>
void ScanOverVariable(Archive& ar)
{
T v;
ar >> v;
}
template<typename T, typename Archive>
void ScanOverArray(Archive& ar, ssize_t count)
{
T v;
for (ssize_t i=0 ; i < count ; ++i)
{
ar >> v;
}
}
template<typename T, typename Archive>
void ScanOverVector(Archive& ar)
{
ssize_t n;
DeserialiseVariableLengthUint(ar,n);
cxAssert(0 <= n);
T x;
for (ssize_t i = 0 ; i != n ; ++i)
{
ar >> x;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Deserialise
template<typename Archive, typename T>
inline void DeserialiseArray(Archive& ar, T* data, ssize_t count)
{
for (ssize_t i=0 ; i < count ; ++i)
{
ar >> data[i];
}
}
template <typename Archive, typename It>
inline void DeserialiseRange(Archive& ar, It begin, It end)
{
while(begin != end)
{
ar >> *begin++;
}
}
template <typename Archive, typename T>
inline void DeserialiseCollectionWithResize(Archive& ar, T& c)
{
CompressedInt<ssize_t> n;
ar >> n;
cxAssert(0 <= n.val);
c.resize(n.val);
for (auto& e : c)
{
ar >> e;
}
}
template <typename V, typename Archive, typename T>
inline void DeserialiseCollectionWithAppend(Archive& ar, T& c)
{
CompressedInt<ssize_t> n;
ar >> n;
cxAssert(0 <= n.val);
c.clear();
for (ssize_t i=0 ; i < n.val ; ++i)
{
V v;
ar >> v;
c.insert(c.end(), v);
}
}
template <typename Archive, typename U, typename V, std::enable_if_t<IsSerialisable<U>::value && IsSerialisable<V>::value, int> = 0>
inline void Deserialise(Archive& ar, std::pair<U,V>& x)
{
ar >> x.first >> x.second;
}
template <typename Archive, typename T, size_t N, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::array<T,N>& x)
{
DeserialiseRange(ar, x.begin(), x.end());
}
template <typename Archive, typename Char, typename Traits, typename Alloc>
inline void Deserialise(Archive& ar, std::basic_string<Char,Traits,Alloc>& x)
{
CompressedInt<ssize_t> n;
ar >> n;
cxAssert(0 <= n.val);
x.resize(n.val);
if (n.val > 0)
{
memcpy(&x[0], ar, n.val * sizeof(Char));
ar += n.val * sizeof(Char);
}
}
template <typename Archive, typename T, typename Alloc, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::vector<T,Alloc>& x)
{
DeserialiseCollectionWithResize(ar, x);
}
template <typename Archive>
inline void Deserialise(Archive& ar, std::vector<bool>& c)
{
CompressedInt<ssize_t> n;
ar >> n;
cxAssert(0 <= n.val);
c.resize(n.val);
for (auto i = c.begin() ; i != c.end() ; ++i)
{
bool v;
ar >> v;
*i = v;
}
}
template <typename Archive, typename T, typename Alloc, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::deque<T,Alloc>& x)
{
DeserialiseCollectionWithResize(ar, x);
}
template <typename Archive, typename T, typename Alloc, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::forward_list<T,Alloc>& c)
{
CompressedInt<ssize_t> n;
ar >> n;
cxAssert(0 <= n.val);
c.clear();
auto p = c.before_begin();
for (ssize_t i=0 ; i < n.val ; ++i)
{
T v;
ar >> v;
p = c.insert_after(p,v);
}
}
template <typename Archive, typename T, typename A, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::list<T,A>& x)
{
DeserialiseCollectionWithAppend<T>(ar, x);
}
template <typename Archive, typename T, ssize_t pageSize, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, xdeque<T,pageSize>& x)
{
DeserialiseCollectionWithResize(ar, x);
}
template <typename Archive>
inline void Deserialise(Archive& ar, VectorOfByte& x)
{
DeserialiseCollectionWithResize(ar, x);
}
template <typename Archive, typename T, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, xvector<T>& x)
{
DeserialiseCollectionWithResize(ar, x);
}
template <typename Archive, typename Key,typename T,typename Compare,typename Alloc, std::enable_if_t<IsSerialisable<Key>::value && IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::map<Key,T,Compare,Alloc>& x)
{
DeserialiseCollectionWithAppend<std::pair<Key,T>> (ar, x);
}
template <typename Archive, typename Key,typename T,typename Compare,typename Alloc, std::enable_if_t<IsSerialisable<Key>::value && IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::multimap<Key,T,Compare,Alloc>& x)
{
DeserialiseCollectionWithAppend<std::pair<Key,T>>(ar, x);
}
template <typename Archive, typename T,typename Compare,typename Alloc, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::set<T,Compare,Alloc>& x)
{
DeserialiseCollectionWithAppend<T>(ar, x);
}
template <typename Archive, typename T,typename Compare,typename Alloc, std::enable_if_t<IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::multiset<T,Compare,Alloc>& x)
{
DeserialiseCollectionWithAppend<T>(ar, x);
}
template <typename Archive, typename Key, typename Hash, typename KeyEqual, typename Alloc, std::enable_if_t<IsSerialisable<Key>::value, int> = 0>
inline void Deserialise(Archive& ar, std::unordered_set<Key,Hash,KeyEqual,Alloc>& x)
{
DeserialiseCollectionWithAppend<Key>(ar, x);
}
template <typename Archive, typename Key, typename Hash, typename KeyEqual, typename Alloc, std::enable_if_t<IsSerialisable<Key>::value, int> = 0>
inline void Deserialise(Archive& ar, std::unordered_multiset<Key,Hash,KeyEqual,Alloc>& x)
{
DeserialiseCollectionWithAppend<Key>(ar, x);
}
template <typename Archive, typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc, std::enable_if_t<IsSerialisable<Key>::value && IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::unordered_map<Key,T,Hash,KeyEqual,Alloc>& x)
{
DeserialiseCollectionWithAppend<std::pair<Key,T>>(ar, x);
}
template <typename Archive, typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc, std::enable_if_t<IsSerialisable<Key>::value && IsSerialisable<T>::value, int> = 0>
inline void Deserialise(Archive& ar, std::unordered_multimap<Key,T,Hash,KeyEqual,Alloc>& x)
{
DeserialiseCollectionWithAppend<std::pair<Key,T>>(ar, x);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// Serialise
template<typename Archive, typename T>
inline void SerialiseArray(Archive& ar, const T* data, ssize_t count)
{
for (ssize_t i=0 ; i < count ; ++i)
{
ar << data[i];
}
}
template <typename Archive, typename It>
inline void SerialiseRange(Archive& ar, It begin, It end)
{
while(begin != end)
{
ar << *begin++;
}
}
template <typename Archive, typename T>
inline void SerialiseCollection(Archive& ar, const T& c)
{
ar << AsCompressedInt(c.size());
for (auto& e : c)
{
ar << e;
}
}
template <typename Archive, typename T, size_t N>
inline void SerialiseCollection(Archive& ar, const std::array<T,N>& c)
{
for (auto& e : c)
{
ar << e;
}
}
template <typename Archive, typename U, typename V>
inline void Serialise(Archive& ar, const std::pair<U,V>& x)
{
ar << x.first << x.second;
}
template <typename Archive, typename T, size_t N>
inline void Serialise(Archive& ar, const std::array<T,N>& x)
{
SerialiseRange(ar, x.begin(), x.end());
}
template <typename Archive, typename Char, typename Traits, typename Alloc>
inline void Serialise(Archive& ar, const std::basic_string<Char,Traits,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T,typename Alloc>
inline void Serialise(Archive& ar, const std::vector<T,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive>
inline void Serialise(Archive& ar, const std::vector<bool>& x)
{
ar << AsCompressedInt(x.size());
for (auto i = x.begin() ; i != x.end() ; ++i)
{
ar << (bool)*i;
}
}
template <typename Archive, typename T, typename Alloc>
inline void Serialise(Archive& ar, const std::deque<T,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T, typename Alloc>
inline void Serialise(Archive& ar, const std::forward_list<T,Alloc>& x)
{
ar << AsCompressedInt(std::distance(x.begin(), x.end()));
for (auto& e : x)
{
ar << e;
}
}
template <typename Archive, typename T, typename Alloc>
inline void Serialise(Archive& ar, const std::list<T,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive>
inline void Serialise(Archive& ar, const VectorOfByte& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T>
inline void Serialise(Archive& ar, const xvector<T>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T,ssize_t pageSize>
inline void Serialise(Archive& ar, const xdeque<T,pageSize>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key,typename T,typename Compare,typename Alloc>
inline void Serialise(Archive& ar, const std::map<Key,T,Compare,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key,typename T,typename Compare,typename Alloc>
inline void Serialise(Archive& ar, const std::multimap<Key,T,Compare,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T,typename Compare,typename Alloc>
inline void Serialise(Archive& ar, const std::set<T,Compare,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename T,typename Compare,typename Alloc>
inline void Serialise(Archive& ar, const std::multiset<T,Compare,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key, typename Hash, typename KeyEqual, typename Alloc>
inline void Serialise(Archive& ar, const std::unordered_set<Key,Hash,KeyEqual,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key, typename Hash, typename KeyEqual, typename Alloc>
inline void Serialise(Archive& ar, const std::unordered_multiset<Key,Hash,KeyEqual,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc>
inline void Serialise(Archive& ar, const std::unordered_map<Key,T,Hash,KeyEqual,Alloc>& x)
{
SerialiseCollection(ar, x);
}
template <typename Archive, typename Key, typename T, typename Hash, typename KeyEqual, typename Alloc>
inline void Serialise(Archive& ar, const std::unordered_multimap<Key,T,Hash,KeyEqual,Alloc>& x)
{
SerialiseCollection(ar, x);
}
#if 0
///////////////////////////////////////////////////////////////////////////////////////////////////
/*
For efficiency provide fast implementations for certain specialisations
such as xvector<int>, xvector<float>, xvector<double>
*/
template <typename Archive, typename T>
void WritePodVector(Archive& ar, const xvector<T>& x)
{
SerialiseVariableLengthUint(ar, x.size());
ar.WriteBuffer(x.data(),x.size() * sizeof(T));
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<char>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<signed char>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<unsigned char>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<short>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<unsigned short>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<int>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<unsigned int>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<long>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<unsigned long>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<long long>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<unsigned long long>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<float>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<double>& x)
{
WritePodVector(ar,x);
}
template <typename Archive>
void Serialise(Archive& ar, const xvector<long double>& x)
{
WritePodVector(ar,x);
}
#endif
} // namespace ceda