Skip to content

Commit 22fadfc

Browse files
Added tuple support to xml_pack/unpack.
1 parent a6c617b commit 22fadfc

6 files changed

Lines changed: 128 additions & 6 deletions

File tree

test/c++17/Makefile

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#define NOGUI if X-windows not installed
44
NOGUI=
55

6-
EXES=testFunctional c++Features
6+
EXES=testFunctional c++Features testXSDGenerate
77
OBJS=
88

99
# note the internal type example cannot be correctly linked with g++ or icc!
@@ -90,11 +90,8 @@ else
9090
if [ -f $@ ]; then touch $@; else echo "*** run make depend on a computer with gcc installed ***"; exit 1; fi
9191
endif
9292

93-
depend: $(OBJS:.o=.d) $(EXES:=.d)
94-
cat *.d >depend
95-
9693
ifneq ($(MAKECMDGOALS),clean)
97-
include depend
94+
include $(OBJS:.o=.d) $(EXES:=.d)
9895
endif
9996

10097
.cc.o:

test/c++17/c++Features.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#ifndef CPPFEATURES_H
22
#define CPPFEATURES_H
3+
#include <tuple>
34

45
struct CppFeatures
56
{

test/c++17/runtests.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#!/bin/bash
2+
set -e
23
for i in $*; do
34
echo $i;
45
./$i;
56
done
7+
8+
# XSD generation test
9+
xmllint --output /dev/null test1.xsd
10+
xmllint --output /dev/null --schema ../XMLSchema.xsd test1.xsd
11+
xmllint --output /dev/null --schema test1.xsd test1.xml

test/c++17/testXSDGenerate.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include "c++Features.h"
2+
#include "xml_pack_base.h"
3+
#include "xml_unpack_base.h"
4+
#include "xsd_generate_base.h"
5+
#include "classdesc_epilogue.h"
6+
#include <assert.h>
7+
using namespace std;
8+
using namespace classdesc;
9+
10+
int main()
11+
{
12+
xsd_generate_t g;
13+
CppFeatures x;
14+
x.tup={10,3}; // set to different from default
15+
string rootTag="root";
16+
xsd_generate(g, rootTag, x);
17+
18+
ofstream f("test1.xsd");
19+
20+
string schema="schema";
21+
g.output(f,schema);
22+
f.close();
23+
f.open("test1.xml");
24+
xml_pack_t xb(f,schema);
25+
xb.prettyPrint=true;
26+
xml_pack(xb,rootTag,x);
27+
28+
// check roundtrip serialisation
29+
CppFeatures y;
30+
xml_unpack_t ux("test1.xml");
31+
ux>>y;
32+
assert(x.tup==y.tup);
33+
}
34+

xml_pack_epilogue.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,38 @@ namespace classdesc_access
2727
void operator()(classdesc::xml_pack_t& t,const classdesc::string& d, const T& a)
2828
{t.pack_notag(d,a);}
2929
};
30+
31+
#if defined(__cplusplus) && __cplusplus>=201703L
32+
33+
template <class... A>
34+
struct access_xml_pack<std::tuple<A...>>
35+
{
36+
template <class T>
37+
void xml_pack_tuple_element(classdesc::xml_pack_t& o, const cd::string& d, T& a)
38+
{
39+
if constexpr (std::tuple_size<T>::value>0)
40+
{
41+
// element name is given by the type name
42+
std::string eName=classdesc::typeName<typename std::tuple_element<0,T>::type>();
43+
eName=eName.substr(0,eName.find('<')); //trim off any template args
44+
// strip leading namespace and qualifiers
45+
const char *e=eName.c_str()+eName.length();
46+
while (e!=eName.c_str() && *(e-1)!=' ' && *(e-1)!=':') e--;
47+
::xml_pack(o,e,std::get<0>(a));
48+
auto tail=classdesc::tupleTail(a);
49+
xml_pack_tuple_element(o,d,tail);
50+
}
51+
}
52+
53+
template <class U>
54+
void operator()(classdesc::xml_pack_t& o, const cd::string& d, U& a)
55+
{
56+
classdesc::xml_pack_t::Tag tag(o,d);
57+
xml_pack_tuple_element(o, d, a);
58+
}
59+
};
60+
#endif
61+
3062
#endif
3163

3264
#ifdef CLASSDESC_XML_UNPACK_BASE_H
@@ -45,6 +77,37 @@ namespace classdesc_access
4577
t.unpack(d,tmp);
4678
}
4779
};
80+
81+
#if defined(__cplusplus) && __cplusplus>=201703L
82+
template <class... A>
83+
struct access_xml_unpack<std::tuple<A...>>
84+
{
85+
template <class T>
86+
void xml_unpack_tuple_element(classdesc::xml_unpack_t& o, const cd::string& d, T& a, int i)
87+
{
88+
if constexpr (std::tuple_size<T>::value>0)
89+
{
90+
::xml_unpack(o,classdesc::idx(d,i),std::get<0>(a));
91+
auto tail=classdesc::tupleTail(a);
92+
xml_unpack_tuple_element(o,d,tail,i+1);
93+
a=std::tuple_cat(std::make_tuple(std::get<0>(a)), tail);
94+
}
95+
}
96+
97+
template <class U>
98+
void operator()(classdesc::xml_unpack_t& o, const cd::string& d, U& a)
99+
{
100+
// element name is given by the type name
101+
std::string eName=classdesc::typeName<typename std::tuple_element<0,std::tuple<A...>>::type>();
102+
eName=eName.substr(0,eName.find('<')); //trim off any template args
103+
// strip leading namespace and qualifiers
104+
const char *e=eName.c_str()+eName.length();
105+
while (e!=eName.c_str() && *(e-1)!=' ' && *(e-1)!=':') e--;
106+
xml_unpack_tuple_element(o,d+"."+e,a,0);
107+
}
108+
};
109+
#endif
110+
48111
#endif
49112
}
50113

xsd_generate_base.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,27 @@ namespace classdesc
398398
processExtraClass(g, d+transformTypeName(typeName<T>()), T());
399399
}
400400
#endif
401+
402+
#if defined(__cplusplus) && __cplusplus>=201703L
403+
template <class... A>
404+
void tuple_element_generate(xsd_generate_t& g, const string& d, const std::tuple<A...>& e)
405+
{
406+
if constexpr (std::tuple_size<std::tuple<A...>>::value>0)
407+
{
408+
xsd_generate(g,d+"."+transformTypeName(typeName<typename std::tuple_element<0,std::tuple<A...>>::type>()),
409+
std::get<0>(e));
410+
tuple_element_generate(g,d,classdesc::tupleTail(e));
411+
}
412+
}
413+
template <class... A>
414+
void xsd_generate(xsd_generate_t& g, const string& d, const std::tuple<A...>& e)
415+
{
416+
g.openType(transformTypeName(typeName<std::tuple<A...>>()),d);
417+
tuple_element_generate(g,d,e);
418+
g.closeType();
419+
g.addMember(tail(d), xsd_typeName<std::tuple<A...>>());
420+
}
421+
#endif
401422

402423
// support for maps
403424
template <class T, class U>
@@ -407,7 +428,7 @@ namespace classdesc
407428
xsd_generate(g,d+".first",a.first);
408429
xsd_generate(g,d+".second",a.second);
409430
g.closeType();
410-
g.addMember(tail(d), xsd_typeName<std::pair<T,U>>());
431+
g.addMember(tail(d), xsd_typeName<std::pair<T,U> >());
411432
}
412433

413434
template <class T>

0 commit comments

Comments
 (0)