13#ifndef CLASSDESC_PACK_BASE_H
14#define CLASSDESC_PACK_BASE_H
33#pragma warning(disable:4512)
40 class pack_error :
public exception
44 pack_error(
const char *s): msg(
"pack:") {msg+=s;}
45 virtual ~pack_error()
throw() {}
46 virtual const char* what()
const throw() {
return msg.c_str();}
50 typedef bool (*xdr_filter)(XDR*,...);
63 template <
class T> xdr_filter XDR_filter(
const T&);
69 Basic_Type(
const T& x){
70 val=(
void*)&x; size=
sizeof(x);
72#if defined(__GNUC__) && !defined(__ICC)
73#pragma GCC diagnostic push
75#pragma GCC diagnostic ignored "-Wuninitialized"
76#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
82#if defined(__GNUC__) && !defined(__ICC)
83#pragma GCC diagnostic pop
103 PtrStoreBase(): cnt(0) {}
104 virtual ~PtrStoreBase() {};
105 virtual void *data()=0;
116 void* data() {
return &d;}
127 void* data() {
return d->data();}
129 PtrStoreRef(
const PtrStoreRef& x): d(x.d) {d && d->cnt++;}
130 PtrStoreRef& operator=(
const PtrStoreRef& x) {d=x.d; d && d->cnt++;
return *
this;}
131 ~PtrStoreRef() {
if (d && d->cnt-- == 0)
delete d;}
139#if __cplusplus < 201103L
140 pack_t operator=(
const pack_t&){
return *
this;}
141 pack_t(
const pack_t&){}
143 pack_t operator=(
const pack_t&)=
delete;
144 pack_t(
const pack_t&)=
delete;
148 void swap_base (pack_t& other){
149 std::swap(f,other.f);
150 std::swap(mode,other.mode);
154 std::swap(ptr_flag,other.ptr_flag);
155 std::swap(alloced,other.alloced);
157 enum mode_t {buf, readf, writef};
167 std::vector<PtrStoreRef> alloced;
172 char* realloc(
char* d,
size_t s) {
174 return (
char*)Realloc(d,s);
176 return (
char*)classdesc::realloc(d,s);
185 if (!
m_data)
throw std::bad_alloc();
195 throw std::bad_alloc();
199 if (fwrite(x.val,x.size,1,f) != 1)
200 throw pack_error(
"file write fail");
203 virtual void popoff(basic_type& x)
207 throw pack_error(
"unexpected end of data");
211 if (fread(x.val,x.size,1,f) != 1)
212 throw pack_error(
"unexpected end of file");
221 pack_t(
const char *fname,
const char *rw):
222 f(fopen(fname,rw)), mode( (rw&&rw[0]==
'w')? writef: readf),
228 if (!f)
throw pack_error(strerror(errno));
230 virtual ~pack_t() {realloc(0);
if (f) fclose(f);}
232#if __cplusplus >= 201103L
233 pack_t(pack_t&& x): f(nullptr),
m_data(nullptr) {swap_base(x);}
234 pack_t& operator=(pack_t&& x) {swap_base(x);
return *
this;}
238 virtual pack_t& reseti() {
m_size=0;
if (f) fseek(f,0,SEEK_SET);
return *
this;}
239 virtual pack_t& reseto() {
m_pos=0;
if (f) fseek(f,0,SEEK_SET);
return *
this;}
240 virtual pack_t& seeki(
long offs) {
241 assert(offs<=0);
m_size+=offs;
242 if (f) fseek(f,offs,SEEK_CUR);
245 virtual pack_t& seeko(
long offs) {
247 if (f) fseek(f,offs,SEEK_CUR);
251 virtual void packraw(
const char *x,
size_t s)
259 if (fwrite(x,s,1,f)!=1)
260 throw pack_error(
"filed to write data to stream");
264#if defined(__GNUC__) && !defined(__ICC)
265#pragma GCC diagnostic push
267#pragma GCC diagnostic ignored "-Warray-bounds"
269 virtual void unpackraw(
char *x,
size_t s)
274 throw pack_error(
"premature end of buffered data");
278 if (fread(x,s,1,f)!=1)
279 throw pack_error(
"premature end of stream");
282#if defined(__GNUC__) && !defined(__ICC)
283#pragma GCC diagnostic pop
286 virtual void swap(pack_t& other) {
287 if (
typeid(*
this)!=
typeid(other))
288 throw pack_error(
"cannot swap differing types");
293 virtual int cmp(
const pack_t& x)
const {
300 bool operator<(
const pack_t& x)
const {
return cmp(x)==-1;}
301 bool operator>(
const pack_t& x)
const {
return cmp(x)==1;}
302 bool operator==(
const pack_t& x)
const {
return cmp(x)==0;}
303 bool operator!=(
const pack_t& x)
const {
return cmp(x)!=0;}
310 return (xb<<x).
cmp(yb<<y);
316 return (xb<<x).
cmp(yb<<y)==0;
319 typedef pack_t unpack_t;
321 template <>
inline string typeName<pack_t>() {
return "classdesc::pack_t";}
324 const int BUFCHUNK=1024;
329 class xdr_pack:
public pack_t
334 xdr_pack(
size_t sz=BUFCHUNK);
335 xdr_pack(
const char *,
const char* rw);
337#if __cplusplus >= 201103L
338 xdr_pack(xdr_pack&& x): input(
nullptr), output(
nullptr) {swap(x);}
339 xdr_pack& operator=(xdr_pack&& x) {swap(x);
return *
this;}
344 virtual xdr_pack& reseti();
345 virtual xdr_pack& reseto();
346 virtual xdr_pack& seeki(
long offs);
347 virtual xdr_pack& seeko(
long offs);
348 virtual void packraw(
const char *x,
size_t sz);
349 virtual void unpackraw(
char *x,
size_t sz);
350 virtual void swap(pack_t& other) {
351 xdr_pack* xdr_other=
dynamic_cast<xdr_pack*
>(&other);
352 if (!xdr_other)
throw pack_error(
"cannot swap differing types");
354 std::swap(asize,xdr_other->asize);
355 std::swap(input,xdr_other->input);
356 std::swap(input,xdr_other->output);
359 template <>
inline string typeName<xdr_pack>() {
return "classdesc::xdr_pack";}
361 typedef pack_t xdr_pack;
375 BinStream(
pack_t& packer): packer(packer) {}
378 operator<<(
const T& o)
380 packer.packraw(
reinterpret_cast<const char*
>(&o),
sizeof(
T));
387 packer.unpackraw(
reinterpret_cast<char*
>(&o),
sizeof(
T));
393 operator<<(
const T& o)
396 for (
typename T::const_iterator i=o.begin(); i!=o.end(); ++i)
407 typename T::value_type v;
408 for (
size_t i=0; i<s; ++i)
422 typename T::value_type v;
423 for (
size_t i=0; i<s; ++i)
432 template <
class T,
class A>
433 inline BinStream& operator<<(
const std::vector<T,A>& o);
435 template <
class T,
class A>
436 inline BinStream& operator>>(std::vector<T,A>& o);
445 template <
class Pack>
struct BinStreamT:
public BinStream
448 BinStreamT(): BinStream(thePack) {}
449 template <
class A1> BinStreamT(A1 a1):
450 BinStream(thePack), thePack(a1) {}
451 template <
class A1,
class A2> BinStreamT(A1 a1, A2 a2):
452 BinStream(thePack), thePack(a1, a2) {}
466 struct unserialisable:
public T
469 unserialisable(
const T& x): T(x) {}
470 unserialisable operator=(
const T& x) {T::operator=(x);
return *
this;}
488#ifndef THROW_PTR_EXCEPTION
493 inline void unpack(unpack_t& targ,
const string& desc,
497 inline void pack(
pack_t& targ,
const string& desc,
509 void pack_onbase(
pack_t& x,
const string& d,
T& a)
513 void unpack_onbase(unpack_t& x,
const string& d,T& a)
517using classdesc::pack_onbase;
518using classdesc::unpack_onbase;
541 switch (targ.ptr_flag)
544#ifndef THROW_PTR_EXCEPTION
545 case classdesc::GRAPH:
548 case classdesc::TREE:
562 void operator()(classdesc::unpack_t& targ,
const classdesc::string& desc, C& arg)
564 switch (targ.ptr_flag)
567#ifndef THROW_PTR_EXCEPTION
568 case classdesc::GRAPH:
571 case classdesc::TREE:
602 template <
class T>
typename
603 enable_if<Not<pack_supported<T> >,
void>::T
604 pack(pack_t& buf,
const string& desc, T& arg)
608 template <
class T>
typename
610 unpack(unpack_t& buf,
const string& desc,
T& arg)
611 {classdesc_access::access_unpack<T>()(buf,desc,arg);}
631 unpack(unpack_t& targ,
const string&,
T& arg)
639 unpack(unpack_t& targ,
const string&,
const T&)
658 T &arg,
int dims,
size_t ncopies,...)
661 va_start(ap,ncopies);
662 for (
int i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
664 for (
size_t i=0; i<ncopies; i++)
pack(targ,desc,(&arg)[i]);
669 int dims,
size_t ncopies,...)
672 va_start(ap,ncopies);
673 for (
int i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
675 for (
size_t i=0; i<ncopies; i++)
unpack(targ,desc,(&arg)[i]);
680 char &arg,
int dims,
size_t ncopies,...)
684 va_start(ap,ncopies);
685 for (i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
687 targ.packraw(&arg,ncopies);
691 char &arg,
int dims,
size_t ncopies,...)
695 va_start(ap,ncopies);
696 for (i=1; i<dims; i++) ncopies*=va_arg(ap,
int);
698 targ.unpackraw(&arg,ncopies);
704 template <
class C,
class R,
class A1>
705 void pack(
pack_t& targ,
const string& desc, R (C::*&arg)(A1))
706 {targ.packraw((
char*)&arg,
sizeof(arg));}
708 template <
class C,
class R,
class A1>
709 void unpack(
pack_t& targ,
const string& desc, R (C::*&arg)(A1))
710 {targ.unpackraw((
char*)&arg,
sizeof(arg));}
712 template<
class C,
class T>
716 template<
class C,
class T>
719 unpack(unpack_t& b,
const string& d, C& o,
T y);
721 template<
class C,
class T>
724 is_object<T> >,
void>::T
726 template<
class C,
class T>
729 is_object<T> >,
void>::T
730 unpack(unpack_t& b,
const string& d, C&,
T* y);
738 void unpack(pack_t& targ,
const string& desc,is_const_static i, T t)
742 template <
class T,
class U>
745 template <
class T,
class U>
769#include "use_mbr_pointers.h"
770CLASSDESC_FUNCTION_NOP(pack)
771CLASSDESC_FUNCTION_NOP(unpack)
775using classdesc::pack_onbase;
776using classdesc::unpack_onbase;
779#pragma omit pack classdesc::string
780#pragma omit pack eco_strstream
781#pragma omit pack xdr_pack
782#pragma omit unpack classdesc::string
783#pragma omit unpack eco_strstream
784#pragma omit unpack xdr_pack
Definition classdesc.h:868
Definition classdesc.h:920
Definition classdesc.h:923
Definition classdesc.h:931
Definition classdesc.h:930
Definition pack_base.h:41
Definition pack_base.h:138
size_t m_size
size of buffer
Definition pack_base.h:160
unsigned recur_max
recursion limit for pack_graph
Definition pack_base.h:166
size_t size() const
size of buffer
Definition pack_base.h:170
char * data()
actual buffer
Definition pack_base.h:169
char * m_data
actual buffer
Definition pack_base.h:159
size_t m_pos
position of read pointer
Definition pack_base.h:161
virtual int cmp(const pack_t &x) const
Definition pack_base.h:293
size_t pos() const
position of read pointer
Definition pack_base.h:171
const char * data() const
actual buffer
Definition pack_base.h:168
void resize(size_t s)
Definition pack_base.h:183
Metaprogramming support for processing functions of multiple arguments.
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition classdesc_access.h:20
Contains definitions related to classdesc functionality.
void pack(pack_t &targ, const string &desc, is_treenode dum, const T *const &arg)
serialise a tree (or DAG)
Definition pack_graph.h:28
void unpack(unpack_t &targ, const string &desc, is_treenode dum, T *&arg)
unserialise a tree.
Definition pack_graph.h:44
Ptr_flag
Definition pack_base.h:93
bool deepEq(const T &x, const T &y)
deep equality of two serialisable items
Definition pack_base.h:314
int deepCmp(const T &x, const T &y)
deep comparison of two serialisable items
Definition pack_base.h:308
Definition classdesc.h:420
Definition pack_base.h:68
Definition classdesc.h:1012
Definition classdesc.h:405
helper for constructing null descriptors
Definition classdesc.h:1106
Definition classdesc.h:423
Definition pack_base.h:101
Definition pack_base.h:114
Definition pack_base.h:54
controlled template specialisation: stolen from boost::enable_if.
Definition classdesc.h:282
Definition pack_base.h:486
class to allow access to private members
Definition classdesc_access.h:21
class to allow access to private members
Definition classdesc_access.h:22