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