Skip to content

Commit b7432b5

Browse files
Added tuple support for pack descriptor, available at C++17, and wired tests in the C++17 suite.
1 parent 0759d2d commit b7432b5

10 files changed

Lines changed: 162 additions & 5 deletions

File tree

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ aegis-all: build latex-docs
119119
# This is now broken, as of OpenJDK 15. Not worth supporting.
120120
# if which javac; then cd java && $(MAKE) && cd ../javaExamples && $(MAKE); fi
121121
cd test && $(MAKE)
122-
cd test/c++11 && $(MAKE)
122+
cd test/c++11 && $(MAKE) sure
123+
cd test/c++17 && $(MAKE) sure
123124
cd RESTProcessExample && $(MAKE)
124125
# -cd objc-examples && $(MAKE)
125126

classdesc.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,83 @@ namespace classdesc
11651165
std::cout<<msg<<std::endl;
11661166
#endif
11671167
}
1168+
1169+
// tuple support
1170+
#if defined(__cplusplus) && __cplusplus>=201103L
1171+
template <class... A> struct tn<std::tuple<A...>>
1172+
{
1173+
// TODO unpack argpack to explicitly name template parameters
1174+
static string name() {return "std::tuple<...>";}
1175+
};
1176+
#endif
1177+
1178+
#if defined(__cplusplus) && __cplusplus>=201703L
1179+
1180+
// The helper function that does the heavy lifting
1181+
template <typename Tuple, std::size_t... Is>
1182+
auto tupleTailImpl(Tuple&& t, std::index_sequence<Is...>) {
1183+
// We add 1 to each index 'Is' to skip the first element (index 0)
1184+
return std::make_tuple(std::get<Is + 1>(std::forward<Tuple>(t))...);
1185+
}
1186+
1187+
template <typename Tuple>
1188+
auto tupleTail(Tuple&& t) {
1189+
constexpr std::size_t N = std::tuple_size<std::decay_t<Tuple>>::value;
1190+
1191+
// Ensure the tuple isn't empty before trying to take the tail
1192+
static_assert(N > 0, "Cannot take the tail of an empty tuple.");
1193+
1194+
if constexpr (N == 1) {
1195+
return std::make_tuple(); // Tail of a single-element tuple is empty
1196+
} else {
1197+
// Generate indices from 0 to N-2
1198+
return tupleTailImpl(std::forward<Tuple>(t),
1199+
std::make_index_sequence<N - 1>{});
1200+
}
1201+
}
1202+
#endif
1203+
1204+
//#if defined(__cplusplus) && __cplusplus>=201103L
1205+
//
1206+
//
1207+
//
1208+
// template <template <class...> class T> struct Tuple1TailType;
1209+
// template <template <class...> class T, class A, class... B>
1210+
// struct Tuple1TailType<class T<A, B...>>
1211+
// {
1212+
// using type=T<B...>;
1213+
// };
1214+
//
1215+
// template <int N, class T> struct TupleTailType;
1216+
//
1217+
// template <class T>
1218+
// struct TupleTailType<1, T>
1219+
// {
1220+
// using type=typename Tuple1TailType<T>::type;
1221+
// };
1222+
//
1223+
// template <int N, template <class...> class T, class A, class... B>
1224+
// struct TupleTailType<N, T<A, B...>>
1225+
// {
1226+
// using type=typename TupleTailType<N-1, B...>::type;
1227+
// };
1228+
//
1229+
// template <class T, int N> struct TupleTail
1230+
// {
1231+
// typename TupleTailType<N, T>::type tuple;
1232+
// TupleTail(const T& x):
1233+
// tuple(std::tuple_cat(std::make_tuple(std::get<N>(x)), TupleTail<T,N+1>(x).tuple)) {}
1234+
// };
1235+
//
1236+
// template <class T> struct TupleTail<T, std::tuple_size<T>::value-1>
1237+
// {
1238+
// std::tuple<
1239+
// typename std::tuple_element<std::tuple_size<T>::value-1,T>::type> tuple;
1240+
// TupleTail(const T& x):
1241+
// tuple(std::get<std::tuple_size<T>::value-1>(x)) {}
1242+
// };
1243+
//#endif
1244+
11681245
}
11691246

11701247

pack_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ namespace classdesc
601601
//generic pack, unpack - defined in pack_stream
602602
template <class T> typename
603603
enable_if<Not<pack_supported<T> >, void>::T
604-
pack(pack_t& buf, const string& desc, T& arg)
604+
pack(pack_t& buf, const string& desc, const T& arg)
605605
{classdesc_access::access_pack<T>()(buf,desc,arg);}
606606

607607

pack_stl.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#if defined(__cplusplus) && __cplusplus>=201103L
1919
#include <array>
20+
#include <tuple>
2021
#endif
2122
#include <iterator>
2223
#include <string>
@@ -302,6 +303,33 @@ namespace classdesc_access
302303
::unpack(targ,desc,arg.second);
303304
}
304305
};
306+
#if defined(__cplusplus) && __cplusplus>=201703L
307+
template <class... A> struct access_pack<std::tuple<A...>>
308+
{
309+
template <class U>
310+
void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
311+
{
312+
::pack(targ,desc,std::get<0>(arg));
313+
if constexpr (std::tuple_size<U>::value>1)
314+
::pack(targ,desc,classdesc::tupleTail(arg));
315+
}
316+
};
317+
318+
template <class... A> struct access_unpack<std::tuple<A...> >
319+
{
320+
template <class U>
321+
void operator()(classdesc::pack_t& targ, const classdesc::string& desc, U& arg)
322+
{
323+
::unpack(targ,desc,std::get<0>(arg));
324+
if constexpr (std::tuple_size<U>::value>1)
325+
{
326+
auto tail=classdesc::tupleTail(arg);
327+
::unpack(targ,desc,tail);
328+
arg=std::tuple_cat(std::make_tuple(std::get<0>(arg)), tail);
329+
}
330+
}
331+
};
332+
#endif
305333
}
306334
#ifdef _CLASSDESC
307335
#pragma omit pack std::plus

pythonExample/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.SUFFIXES: .c .cc .o .d .h .cd
22
OBJS=pythonExample.o
3-
CFLAGS=-g `pkg-config --cflags python3` -I.. -I. -I../json5_parser/json5_parser -fPIC -std=c++11 -DUSE_UNROLLED
3+
CFLAGS=-g `pkg-config --cflags python3` -I.. -I. -I../json5_parser/json5_parser -fPIC -std=c++17 -DUSE_UNROLLED
44
VPATH=..
55

66
example.so: $(OBJS)

test/c++11/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ endif
107107
../../classdesc -I .. -nodef -typeName -i $< pack unpack >$@
108108
# check that duplicate typeNames can be issued
109109
# ../classdesc -I .. -nodef -typeName <$< >>$@
110-
../../classdesc -I .. -nodef -typeName -respect_private -i $< xml_pack xml_unpack dump xsd_generate >>$@
110+
../../classdesc -I .. -nodef -typeName -respect_private -i $< xml_pack xml_unpack json_pack json_unpack dump xsd_generate >>$@
111111

112112
xml_unpack_base.cd: xml_unpack_base.h
113113
../../classdesc -I .. -nodef pack unpack <$< >$@

test/c++17/Makefile

Lines changed: 1 addition & 1 deletion
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
6+
EXES=testFunctional c++Features
77
OBJS=
88

99
# note the internal type example cannot be correctly linked with g++ or icc!

test/c++17/c++Features.cc

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// why are these lines needed?? Bug in gcc?
2+
#include <vector>
3+
#include <unordered_map>
4+
#include <classdesc.h>
5+
namespace std
6+
{
7+
template <class T>
8+
struct hash<vector<T> >
9+
{
10+
unsigned operator()(const vector<T>& x) const {
11+
unsigned r=0;
12+
for (auto i: x)
13+
r ^= hash<T>()(i);
14+
return r;
15+
}
16+
};
17+
}
18+
19+
#include "pack_stl.h"
20+
#include "c++Features.h"
21+
#include "classdesc_epilogue.h"
22+
23+
using namespace classdesc;
24+
25+
26+
using std::cout;
27+
using std::endl;
28+
29+
int main()
30+
{
31+
pack_t b;
32+
CppFeatures x, y;
33+
x.tup={10,3}; // set to different from default
34+
b<<x>>y;
35+
assert(x.tup==y.tup); // checks brace initialiser
36+
37+
// make sure various C++17 types have valid typenames
38+
cout << typeName<std::tuple<int,int>>() << endl;
39+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef CPPFEATURES_H
2+
#define CPPFEATURES_H
3+
4+
struct CppFeatures
5+
{
6+
std::tuple<int, int> tup{3,2};
7+
};
8+
9+
10+
11+
#include "c++Features.cd"
12+
#endif

test/c++17/testFunctional

240 KB
Binary file not shown.

0 commit comments

Comments
 (0)