Skip to content

Commit 0d5a1b4

Browse files
author
huangxiyuan
committed
support thirdparty class
1 parent bb106b9 commit 0d5a1b4

File tree

11 files changed

+264
-8
lines changed

11 files changed

+264
-8
lines changed

README.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ x2struct
1818
* [check exist](#check-exist)
1919
* [local class](#local-class)
2020
* [customize type](#customize-type)
21+
* [thirdparty class](#thirdparty-class)
2122
* [Format indent](#format-indent)
2223
* [xml bson libconfig](#xml-bson-libconfig)
2324
* [Generate Golang struct](#generate-golang-struct)
@@ -367,6 +368,50 @@ Format indent
367368
- last two parameters of tojson control format indent
368369
369370
371+
thirdparty class
372+
----
373+
- need c++11 support
374+
- use XTOSTRUCT_OUT instead of XTOSTRUCT
375+
376+
```c++
377+
#include <sys/time.h>
378+
#include "x2struct/x2struct.hpp"
379+
380+
using namespace std;
381+
382+
/*
383+
struct timeval {
384+
time_t tv_sec;
385+
suseconds_t tv_usec;
386+
};
387+
*/
388+
389+
// timeval is thirdparty struct
390+
XTOSTRUCT_OUT(timeval, O(tv_sec, tv_usec));
391+
392+
struct T {
393+
int a;
394+
string b;
395+
timeval t;
396+
XTOSTRUCT(O(a, b, t));
397+
};
398+
399+
400+
int main(int argc, char *argv[]) {
401+
T t;
402+
T r;
403+
t.a = 123;
404+
t.b = "x2struct";
405+
t.t.tv_sec = 888;
406+
t.t.tv_usec = 999;
407+
string s = x2struct::X::tojson(t);
408+
cout<<s<<endl;
409+
x2struct::X::loadjson(s, r, false);
410+
cout<<r.a<<','<<r.b<<','<<r.t.tv_sec<<','<<r.t.tv_usec<<endl;
411+
return 0;
412+
}
413+
```
414+
370415
xml bson libconfig
371416
----
372417
- need to modify [config.h](config.h) to enable

README.zh-cn.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ x2struct
1616
* [检查是否存在](#检查是否存在)
1717
* [局部类](#局部类)
1818
* [自定义类型](#自定义类型)
19+
* [第三方类和结构体](#第三方类和结构体)
1920
* [格式化缩进](#格式化缩进)
2021
* [xml bson libconfig](#xml-bson-libconfig)
2122
* [生成Golang结构体](#生成golang结构体)
@@ -365,6 +366,50 @@ int main(int argc, char *argv[]) {
365366
}
366367
```
367368
369+
第三方类和结构体
370+
----
371+
- 需要C++11支持
372+
- 用XTOSTRUCT_OUT而非XTOSTRUCT
373+
374+
```c++
375+
#include <sys/time.h>
376+
#include "x2struct/x2struct.hpp"
377+
378+
using namespace std;
379+
380+
/*
381+
struct timeval {
382+
time_t tv_sec;
383+
suseconds_t tv_usec;
384+
};
385+
*/
386+
387+
// timeval is thirdparty struct
388+
XTOSTRUCT_OUT(timeval, O(tv_sec, tv_usec));
389+
390+
struct T {
391+
int a;
392+
string b;
393+
timeval t;
394+
XTOSTRUCT(O(a, b, t));
395+
};
396+
397+
398+
int main(int argc, char *argv[]) {
399+
T t;
400+
T r;
401+
t.a = 123;
402+
t.b = "x2struct";
403+
t.t.tv_sec = 888;
404+
t.t.tv_usec = 999;
405+
string s = x2struct::X::tojson(t);
406+
cout<<s<<endl;
407+
x2struct::X::loadjson(s, r, false);
408+
cout<<r.a<<','<<r.b<<','<<r.t.tv_sec<<','<<r.t.tv_usec<<endl;
409+
return 0;
410+
}
411+
```
412+
368413
格式化缩进
369414
----
370415
- tojson的最后两个参数控制

bson_writer.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,29 @@ class BsonWriter {
187187
return *this;
188188
}
189189

190+
191+
#ifdef X_SUPPORT_C0X
192+
// class/struct that not defined macro XTOSTRUCT
193+
template <typename T, typename std::enable_if<!x_has_x2struct<T>::value, int>::type = 0>
194+
BsonWriter& convert(const char*key, const T& data, x_for_class(T, int) *unused=0) {
195+
(void)unused;
196+
if (_type!=top || key[0]!='\0') {
197+
BsonWriter child(key, _bson, doc);
198+
x_struct_to_str(child, "", data);
199+
} else {
200+
x_struct_to_str(*this, "", data);
201+
}
202+
return *this;
203+
}
204+
205+
// class/struct that defined macro XTOSTRUCT
206+
template <typename T, typename std::enable_if<x_has_x2struct<T>::value, int>::type = 0>
207+
BsonWriter& convert(const char*key, const T& data) {
208+
#else
190209
template <typename T>
191210
BsonWriter& convert(const char*key, const T& data, x_for_class(T, int) *p=0) {
192211
(void)p;
212+
#endif
193213
if (_type!=top || key[0]!='\0') {
194214
BsonWriter child(key, _bson, doc);
195215
data.__struct_to_str(child, "");

config_writer.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,27 @@ class ConfigWriter {
260260
this->object_end();
261261
}
262262

263+
264+
#ifdef X_SUPPORT_C0X
265+
// class/struct that not defined macro XTOSTRUCT
266+
template <typename T, typename std::enable_if<!x_has_x2struct<T>::value, int>::type = 0>
267+
void convert(const char*key, const T& data, x_for_class(T, int) *unused=0) {
268+
(void)unused;
269+
indent();
270+
x2struct_set_key(key);
271+
this->object_begin();
272+
x_struct_to_str(*this, key, data);
273+
this->object_end();
274+
}
275+
276+
// class/struct that defined macro XTOSTRUCT
277+
template <typename T, typename std::enable_if<x_has_x2struct<T>::value, int>::type = 0>
278+
void convert(const char*key, const T& data) {
279+
#else
263280
template <typename T>
264281
void convert(const char*key, const T& data, x_for_class(T, int) *p=0) {
265282
(void)p;
283+
#endif
266284
indent();
267285
x2struct_set_key(key);
268286
this->object_begin();

json_writer.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,25 @@ class JsonWriter {
245245
this->object_end();
246246
}
247247

248+
#ifdef X_SUPPORT_C0X
249+
// class/struct that not defined macro XTOSTRUCT
250+
template <typename T, typename std::enable_if<!x_has_x2struct<T>::value, int>::type = 0>
251+
void convert(const char*key, const T& data, x_for_class(T, int) *unused=0) {
252+
(void)unused;
253+
x2struct_set_key(key);
254+
this->object_begin();
255+
x_struct_to_str(*this, key, data);
256+
this->object_end();
257+
}
258+
259+
// class/struct that defined macro XTOSTRUCT
260+
template <typename T, typename std::enable_if<x_has_x2struct<T>::value, int>::type = 0>
261+
void convert(const char*key, const T& data) {
262+
#else
248263
template <typename T>
249264
void convert(const char*key, const T& data, x_for_class(T, int) *p=0) {
250265
(void)p;
266+
#endif
251267
x2struct_set_key(key);
252268
this->object_begin();
253269
data.__struct_to_str(*this, key);

test/example.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,19 @@ struct condition {
3636
XTOSTRUCT(M(url));
3737
};
3838

39+
#ifdef X_SUPPORT_C0X
40+
struct sub {
41+
int a;
42+
string b;
43+
};
44+
XTOSTRUCT_OUT(sub, M(a), O(b));
45+
#else
3946
struct sub {
4047
int a;
4148
string b;
4249
XTOSTRUCT(M(a), O(b));
4350
};
51+
#endif
4452

4553
struct xstruct {
4654
int id;

test/makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ check:
3939
./$@
4040
@-rm $@
4141

42+
checkc11:
43+
$(GPP) -o $@ -Wextra -Wall check.cpp $(INC) $(LIBCONFIG) $(LIBBSON) -std=c++11
44+
./$@
45+
@-rm $@
46+
4247
nt:
4348
$(GPP) -o $@ check.cpp $(INC) $(LIBCONFIG) $(LIBBSON) -std=c++11 -DXNT
4449
./$@

traits.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,31 @@
2525
using namespace std;
2626

2727
#if __GXX_EXPERIMENTAL_CXX0X__ || _MSC_VER>=1700
28+
29+
#define X_SUPPORT_C0X
30+
#define X_SELF __x_self
31+
32+
namespace x2struct {
33+
34+
template <typename T>
35+
struct x_has_x2struct
36+
{
37+
typedef char YES;
38+
typedef char NO[2];
39+
40+
template <typename C> static YES& check(decltype(&C::__x_cond));
41+
template <typename> static NO& check(...);
42+
43+
static bool const value = sizeof(check<T>(0)) == sizeof(YES);
44+
};
45+
46+
struct x_fake_set {
47+
void insert(const std::string &s){(void)s;}
48+
};
49+
50+
}
51+
52+
2853
//template <class T>
2954
//using x_for_class = typename std::enable_if<std::is_class<T>::value, int>::type;
3055

@@ -39,6 +64,8 @@ using namespace std;
3964

4065
#else // C11
4166

67+
#define X_SELF this
68+
4269
namespace x2struct {
4370

4471
template<bool B, class T = void>

x2struct.hpp

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <set>
2727
#include <stdexcept>
2828

29+
#include "traits.h"
2930
#include "util.h"
3031
#include "xreader.h"
3132

@@ -54,7 +55,6 @@
5455
#include "go_writer.h"
5556
#endif
5657

57-
#include "traits.h"
5858

5959
//#include <iostream>
6060
//using namespace std;
@@ -163,6 +163,8 @@ class X {
163163
};
164164

165165
} // namespace
166+
#else
167+
#include "traits.h"
166168
#endif // XTOSTRUCT_MACRO_TEST
167169

168170
#define X_STRUCT_FUNC_COMMON \
@@ -174,13 +176,24 @@ public: \
174176
return __x_has_string.find(name)!=__x_has_string.end(); \
175177
}
176178

179+
#ifndef X_SUPPORT_C0X
177180
#define X_STRUCT_FUNC_TOX_BEGIN \
178181
template<typename DOC> \
179182
void __x_to_struct(DOC& obj) {
183+
#else
184+
#define X_STRUCT_FUNC_TOX_BEGIN \
185+
template<typename DOC> \
186+
void __x_to_struct(DOC& obj) { auto X_SELF = this;
187+
188+
#define X_STRUCT_FUNC_TOX_BEGIN_OUT(NAME) \
189+
template<typename DOC> \
190+
void x_str_to_struct(DOC& obj, NAME& __xval__) { x2struct::x_fake_set __x_has_string; auto X_SELF = &__xval__;
191+
192+
#endif
180193

181194
// optional
182195
#define X_STRUCT_ACT_TOX_O(M) \
183-
if (obj.convert(#M, M) && obj.set_has()) { \
196+
if (obj.convert(#M, X_SELF->M) && obj.set_has()) { \
184197
__x_has_string.insert(#M); \
185198
}
186199

@@ -192,13 +205,13 @@ public: \
192205
if (obj.set_has()) { \
193206
__x_has_string.insert(#M); \
194207
} \
195-
M = __tmp; \
208+
X_SELF->M = __tmp; \
196209
} \
197210
}
198211

199212
// mandatory
200213
#define X_STRUCT_ACT_TOX_M(M) \
201-
if (obj.convert(#M, M)) { \
214+
if (obj.convert(#M, X_SELF->M)) { \
202215
if (obj.set_has()) __x_has_string.insert(#M); \
203216
} else { \
204217
obj.md_exception(#M); \
@@ -210,9 +223,9 @@ public: \
210223
bool md = false; \
211224
std::string __alias__name__ = obj.hasa(#M, A_NAME, &md); \
212225
const char*__an = __alias__name__.c_str(); \
213-
if (obj.convert(__an, M)) { \
226+
if (obj.convert(__an, X_SELF->M)) { \
214227
if (obj.set_has()) __x_has_string.insert(#M); \
215-
} else if (obj.convert(#M, M)) { \
228+
} else if (obj.convert(#M, X_SELF->M)) { \
216229
if (obj.set_has()) __x_has_string.insert(#M); \
217230
} else if (md) { \
218231
obj.md_exception(__an); \
@@ -229,15 +242,26 @@ public: \
229242

230243

231244
// struct to string
245+
#ifndef X_SUPPORT_C0X
232246
#define X_STRUCT_FUNC_TOS_BEGIN \
233247
template <class CLASS> \
234248
void __struct_to_str(CLASS& obj, const char *root) const { (void)root;
249+
#else
250+
#define X_STRUCT_FUNC_TOS_BEGIN \
251+
template <class CLASS> \
252+
void __struct_to_str(CLASS& obj, const char *root) const { (void)root;auto X_SELF = this;
253+
254+
#define X_STRUCT_FUNC_TOS_BEGIN_OUT(NAME) \
255+
template <class CLASS> \
256+
void x_struct_to_str(CLASS& obj, const char *root, const NAME&__xval__) { (void)root;auto X_SELF = &__xval__;
257+
258+
#endif
235259

236260
#define X_STRUCT_ACT_TOS_O(M) \
237-
obj.convert(#M, M);
261+
obj.convert(#M, X_SELF->M);
238262

239263
#define X_STRUCT_ACT_TOS_A(M, A_NAME) \
240-
obj.convert(x2struct::Util::alias_parse(#M, A_NAME, obj.type(), 0).c_str(), M);
264+
obj.convert(x2struct::Util::alias_parse(#M, A_NAME, obj.type(), 0).c_str(), X_SELF->M);
241265

242266
// Inheritance
243267
#define X_STRUCT_ACT_TOS_I(B) B::__struct_to_str(obj, root);
@@ -482,6 +506,11 @@ public: \
482506
X_STRUCT_FUNC_TOS_BEGIN X_STRUCT_N(X_STRUCT_L1, X_STRUCT_L1_TOS, __VA_ARGS__) X_STRUCT_FUNC_TOS_END
483507
#endif
484508

509+
// for class/struct that could not modify(could not add XTOSTUCT macro)
510+
#define XTOSTRUCT_OUT(NAME, ...) \
511+
X_STRUCT_FUNC_TOX_BEGIN_OUT(NAME) X_STRUCT_N(X_STRUCT_L1, X_STRUCT_L1_TOX, __VA_ARGS__) X_STRUCT_FUNC_TOX_END \
512+
X_STRUCT_FUNC_TOS_BEGIN_OUT(NAME) X_STRUCT_N(X_STRUCT_L1, X_STRUCT_L1_TOS, __VA_ARGS__) X_STRUCT_FUNC_TOS_END
513+
485514
/////////////////////////////////////////////////////////////////////
486515
// for local class, gen code without template (no template) BEGIN
487516
/////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)