1 /* /libs/serialization/xml_performance/macro.hpp *******************************
2 
3 (C) Copyright 2010 Bryce Lelbach
4 
5 Use, modification and distribution is subject to the Boost Software License,
6 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 http://www.boost.org/LICENSE_1_0.txt)
8 
9 *******************************************************************************/
10 
11 #if !defined(BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP)
12 #define BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP
13 
14 #if defined(_MSC_VER)
15   #pragma once
16 #endif
17 
18 #include <boost/preprocessor.hpp>
19 
20 #if !defined(BSL_NODE_MAX)
21   #define BSL_NODE_MAX 4
22 #endif
23 
24 #if !defined(BSL_DEPTH)
25   #define BSL_DEPTH 2
26 #endif
27 
28 #if !defined(BSL_ROUNDS)
29   #define BSL_ROUNDS 256
30 #endif
31 
32 #if !defined(BSL_TYPE)
33   #define BSL_TYPE int
34 #endif
35 
36 #if !defined(BSL_SAVE_TMPFILE)
37   #define BSL_SAVE_TMPFILE 0
38 #endif
39 
40 #if !defined(BSL_RESULTS_FILE)
41   #define BSL_RESULTS_FILE                                \
42     BOOST_PP_STRINGIZE(BSL_TYPE)                          \
43     BOOST_PP_STRINGIZE(BSL_EXP(BSL_NODE_MAX, BSL_DEPTH))  \
44     "_results.xml"                                        \
45   /**/
46 #endif
47 
48 // utility print macro
49 
50 #define BSL_PRINT(Z, N, T) T
51 
52 // preprocessor power function, BSL_EXP
53 
54 #define BSL_EXP_PRED(B, D) BOOST_PP_TUPLE_ELEM(3, 0, D)
55 
56 #define BSL_EXP_OP(B, D)                                                       \
57    (                                                                           \
58       BOOST_PP_DEC(BOOST_PP_TUPLE_ELEM(3, 0, D)),                              \
59       BOOST_PP_TUPLE_ELEM(3, 1, D),                                            \
60       BOOST_PP_MUL_D(                                                          \
61          B,                                                                    \
62          BOOST_PP_TUPLE_ELEM(3, 2, D),                                         \
63          BOOST_PP_TUPLE_ELEM(3, 1, D)                                          \
64       )                                                                        \
65    )                                                                           \
66    /**/
67 
68 #define BSL_EXP(X, N)                                                          \
69   BOOST_PP_TUPLE_ELEM(                                                         \
70     3, 2, BOOST_PP_WHILE(BSL_EXP_PRED, BSL_EXP_OP, (N, X, 1))                  \
71   )                                                                            \
72   /**/
73 
74 // boost::archive::xml::node macros
75 
76 #define BSL_NODE_DECL_MEMBER(Z, N, _)   T ## N  element ## N  ;
77 #define BSL_NODE_DECL_NONE(Z, N, _)     unused_type  element ## N  ;
78 #define BSL_NODE_xDECL_CTOR()           node (void) { }
79 
80 #define BSL_NODE_DECL_CTOR(P)                                                  \
81   BOOST_PP_IF(P,                                                               \
82     BSL_NODE_xDECL_CTOR,                                                       \
83     BOOST_PP_EMPTY                                                             \
84   )()                                                                          \
85   /**/
86 
87 #define BSL_NODE_SERIALIZE(Z, N, _)                                            \
88   & BOOST_SERIALIZATION_NVP(BOOST_PP_CAT(element, N))                          \
89   /**/
90 
91 #define BSL_NODE_INIT_LIST(Z, N, _)                                            \
92   BOOST_PP_COMMA_IF(N)  BOOST_PP_CAT(element, N)                               \
93   BOOST_PP_LPAREN() BOOST_PP_CAT(p, N) BOOST_PP_RPAREN()                       \
94   /**/
95 
96 #define BSL_NODE_DECL(Z, N, _)                                                 \
97   template<BOOST_PP_ENUM_PARAMS_Z(Z, N, typename T)>                           \
98   struct node<                                                                 \
99     BOOST_PP_ENUM_PARAMS_Z(Z, N, T)                                            \
100     BOOST_PP_COMMA_IF(N)                                                       \
101     BOOST_PP_ENUM_ ## Z(BOOST_PP_SUB(BSL_NODE_MAX, N), BSL_PRINT, unused_type) \
102   > {                                                                          \
103     BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_DECL_MEMBER, _)                          \
104                                                                                \
105     BOOST_PP_REPEAT_FROM_TO_ ## Z(N, BSL_NODE_MAX, BSL_NODE_DECL_NONE, _)      \
106                                                                                \
107     template<class ARC>                                                        \
108     void serialize (ARC& ar, const unsigned int) {                             \
109       ar BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_SERIALIZE, _);                      \
110     }                                                                          \
111                                                                                \
112     BSL_NODE_DECL_CTOR(N)                                                      \
113                                                                                \
114     node (BOOST_PP_ENUM_BINARY_PARAMS_Z(Z, N, T, p)):                          \
115       BOOST_PP_REPEAT_ ## Z(N, BSL_NODE_INIT_LIST, _) { }                      \
116   };                                                                           \
117   /**/
118 
119 // instantiation macros
120 
121 #define BSL_INST_BASE(Z, N, L)                                                 \
122   T0 T0 ## _ ## N(BOOST_PP_ENUM_ ## Z(                                         \
123     BSL_NODE_MAX, BSL_PRINT,                                                   \
124     boost::archive::xml::random<BSL_TYPE> BOOST_PP_LPAREN() BOOST_PP_RPAREN()  \
125   ));                                                                          \
126   /**/
127 
128 #define BSL_INST_yNODES(Z, N, L)                                               \
129   BOOST_PP_COMMA_IF(N)                                                         \
130   BOOST_PP_CAT(T,                                                              \
131     BOOST_PP_CAT(BOOST_PP_LIST_AT(L, 1),                                       \
132       BOOST_PP_CAT(_,                                                          \
133         BOOST_PP_ADD(N,                                                        \
134           BOOST_PP_LIST_AT(L, 0)                                               \
135         )                                                                      \
136       )                                                                        \
137     )                                                                          \
138   )                                                                            \
139   /**/
140 
141 #define BSL_INST_xNODES(Z, N, L)                                               \
142   T ## L T ## L ## _ ## N(                                                     \
143     BOOST_PP_REPEAT_ ## Z(                                                     \
144       BSL_NODE_MAX, BSL_INST_yNODES,                                           \
145       (BOOST_PP_MUL(N, BSL_NODE_MAX), (BOOST_PP_SUB(L, 1), BOOST_PP_NIL))      \
146     )                                                                          \
147   );                                                                           \
148   /**/
149 
150 #define BSL_INST_NODES(Z, N, L)                                                \
151   BOOST_PP_REPEAT_ ## Z(                                                       \
152     BSL_EXP(BSL_NODE_MAX, BOOST_PP_SUB(BSL_DEPTH, N)),                         \
153     BSL_INST_xNODES, N                                                         \
154   )                                                                            \
155   /**/
156 
157 #define BSL_TYPEDEF_NODES(Z, N, L)                                             \
158   typedef boost::archive::xml::node<                                           \
159     BOOST_PP_ENUM_ ## Z(                                                       \
160       BSL_NODE_MAX, BSL_PRINT, BOOST_PP_CAT(T, BOOST_PP_SUB(N, 1))             \
161     )                                                                          \
162   > T ## N;                                                                    \
163   /**/
164 
165 // main macro
166 
167 #define BSL_MAIN                                                               \
168   int main (void) {                                                            \
169     using namespace boost::archive;                                            \
170     using namespace boost::archive::xml;                                       \
171                                                                                \
172     typedef node<BOOST_PP_ENUM(BSL_NODE_MAX, BSL_PRINT, BSL_TYPE)> T0;         \
173                                                                                \
174     BOOST_PP_REPEAT_FROM_TO(1, BSL_DEPTH, BSL_TYPEDEF_NODES, _)                \
175                                                                                \
176     typedef node<BOOST_PP_ENUM(                                                \
177       BSL_NODE_MAX, BSL_PRINT,                                                 \
178       BOOST_PP_CAT(T, BOOST_PP_SUB(BSL_DEPTH, 1))                              \
179     )> HEAD;                                                                   \
180                                                                                \
181     result_set results;                                                        \
182     std::size_t rounds = BSL_ROUNDS;                                           \
183                                                                                \
184     while (rounds --> 0) {                                                     \
185       BOOST_PP_REPEAT(BSL_EXP(BSL_NODE_MAX, BSL_DEPTH), BSL_INST_BASE, _)      \
186                                                                                \
187       BOOST_PP_REPEAT_FROM_TO(1, BSL_DEPTH, BSL_INST_NODES, _)                 \
188                                                                                \
189       HEAD h(BOOST_PP_ENUM_PARAMS(                                             \
190         BSL_NODE_MAX,                                                          \
191         BOOST_PP_CAT(T, BOOST_PP_CAT(BOOST_PP_SUB(BSL_DEPTH, 1), _))           \
192       ));                                                                      \
193                                                                                \
194       std::string fn = save_archive(h);                                        \
195                                                                                \
196       std::pair<double, HEAD> r = restore_archive<HEAD>(fn);                   \
197                                                                                \
198       std::cout << "round "                                                    \
199                 << ((BSL_ROUNDS - 1) - rounds)                                 \
200                 << " -> " << fn << "\n";                                       \
201                                                                                \
202       BOOST_PP_IF(BSL_SAVE_TMPFILE,                                            \
203         BOOST_PP_EMPTY(),                                                      \
204         std::remove(fn.c_str());                                               \
205       )                                                                        \
206                                                                                \
207       results.entries.push_back(entry(                                         \
208          BOOST_PP_STRINGIZE(BSL_TYPE),                                         \
209          BSL_EXP(BSL_NODE_MAX, BSL_DEPTH), r.first                             \
210       ));                                                                      \
211     }                                                                          \
212                                                                                \
213     std::fstream fs(BSL_RESULTS_FILE, std::fstream::in);                       \
214                                                                                \
215     if (fs.good()) {                                                           \
216       xml_iarchive ia(fs);                                                     \
217       ia >> BOOST_SERIALIZATION_NVP(results);                                  \
218       fs.close();                                                              \
219     }                                                                          \
220                                                                                \
221     fs.open(BSL_RESULTS_FILE, std::fstream::out | std::fstream::trunc);        \
222     xml_oarchive oa(fs);                                                       \
223     oa << BOOST_SERIALIZATION_NVP(results);                                    \
224                                                                                \
225     fs.close();                                                                \
226   }                                                                            \
227   /**/
228 
229 #endif // BOOST_SERIALIZATION_XML_PERFORMANCE_MACRO_HPP
230