21 #define BOOST_TEST_MODULE libjmmcg_tests
22 #include <boost/test/included/unit_test.hpp>
23 #include <boost/mpl/size.hpp>
25 #include "core/msm.hpp"
27 #include "core/ave_deviation_meter.hpp"
28 #include "core/stats_output.hpp"
33 using namespace libjmmcg;
61 operator<<(
std::ostream &os,
states const s)
noexcept(
false) {
62 os<<
static_cast<
long>(s);
71 using argument_type=data;
73 template<
auto state,
auto next,
class Params>
74 void operator()(Params &p)
const noexcept(
true) {
79 using argument_type=data;
81 template<
auto state,
auto next,
class Params>
82 void operator()(Params &p)
const noexcept(
true) {
87 using argument_type=data;
89 template<
auto state,
auto next,
class Params>
90 void operator()(Params &p)
const noexcept(
true) {
95 using argument_type=data;
97 template<
auto state,
auto next,
class Params>
98 void operator()(Params &p)
const noexcept(
true) {
103 using argument_type=data;
105 template<
auto state,
auto next,
class Params>
111 using argument_type=data;
113 template<
auto state,
auto next,
class Params>
119 using argument_type=data;
121 template<
auto state,
auto next,
class Params>
127 using argument_type=data;
129 template<
auto state,
auto next,
class Params>
135 using argument_type=data;
137 template<
auto state,
auto next,
class Params>
143 using argument_type=data;
145 template<
auto state,
auto next,
class Params>
152 struct state_machine_t
final : msm::unroll::state_transition_table<state_machine_t> {
154 using transition_table=rows<
155 row_t::row<states::start, assign_event, states::end>,
156 row_t::row<states::assign, assign_event, states::end>,
157 row_t::row<states::assign1, assign_event1, states::end>,
158 row_t::row<states::assign2, assign_event2, states::end>,
159 row_t::row<states::assign3, assign_event3, states::end>,
160 row_t::row<states::assign4, assign_event4, states::end>,
161 row_t::row<states::assign5, assign_event5, states::end>,
162 row_t::row<states::assign6, assign_event6, states::end>,
163 row_t::row<states::assign7, assign_event7, states::end>,
164 row_t::row<states::assign8, assign_event8, states::end>,
165 row_t::row<states::assign9, assign_event9, states::end>
172 msm.process(state, p);
179 struct state_machine_t
final : msm::jump_table::state_transition_table<state_machine_t> {
181 using transition_table=rows<
182 row_t::row<states::start, assign_event, states::end>,
183 row_t::row<states::assign, assign_event, states::end>,
184 row_t::row<states::assign1, assign_event1, states::end>,
185 row_t::row<states::assign2, assign_event2, states::end>,
186 row_t::row<states::assign3, assign_event3, states::end>,
187 row_t::row<states::assign4, assign_event4, states::end>,
188 row_t::row<states::assign5, assign_event5, states::end>,
189 row_t::row<states::assign6, assign_event6, states::end>,
190 row_t::row<states::assign7, assign_event7, states::end>,
191 row_t::row<states::assign8, assign_event8, states::end>,
192 row_t::row<states::assign9, assign_event9, states::end>
199 msm.process(state, p);
206 struct state_machine_t
final : msm::computed_goto::state_transition_table<state_machine_t> {
208 using transition_table=rows<
209 row_t::row<states::start, assign_event, states::end>,
210 row_t::row<states::assign, assign_event, states::end>,
211 row_t::row<states::assign1, assign_event1, states::end>,
212 row_t::row<states::assign2, assign_event2, states::end>,
213 row_t::row<states::assign3, assign_event3, states::end>,
214 row_t::row<states::assign4, assign_event4, states::end>,
215 row_t::row<states::assign5, assign_event5, states::end>,
216 row_t::row<states::assign6, assign_event6, states::end>,
217 row_t::row<states::assign7, assign_event7, states::end>,
218 row_t::row<states::assign8, assign_event8, states::end>,
219 row_t::row<states::assign9, assign_event9, states::end>
226 msm.process(state, p);
233 struct state_machine_t
final : msm::hash::state_transition_table<state_machine_t> {
235 using transition_table=rows<
236 row_t::row<states::start, assign_event, states::end>,
237 row_t::row<states::assign, assign_event, states::end>,
238 row_t::row<states::assign1, assign_event1, states::end>,
239 row_t::row<states::assign2, assign_event2, states::end>,
240 row_t::row<states::assign3, assign_event3, states::end>,
241 row_t::row<states::assign4, assign_event4, states::end>,
242 row_t::row<states::assign5, assign_event5, states::end>,
243 row_t::row<states::assign6, assign_event6, states::end>,
244 row_t::row<states::assign7, assign_event7, states::end>,
245 row_t::row<states::assign8, assign_event8, states::end>,
246 row_t::row<states::assign9, assign_event9, states::end>
253 msm.process(state, p);
259 using state_machines_t=boost::mpl::list<
266 BOOST_AUTO_TEST_SUITE(msm_tests)
268 BOOST_AUTO_TEST_SUITE(performance, *stats_to_csv::make_fixture(
"msm_performance.csv"))
275 BOOST_AUTO_TEST_CASE_TEMPLATE(state_changes, state_machine_t, state_machines_t) {
276 const unsigned short loops_for_conv=50;
277 const double perc_conv_estimate=5.0;
278 #ifdef JMMCG_PERFORMANCE_TESTS
279 const unsigned long test_size=10000000U;
281 const unsigned long test_size=10U;
284 const std::pair<timed_results_t,
bool> timed_results(compute_average_deviation<timed_results_t::value_type>(
290 std::mt19937_64 gen(42);
291 std::uniform_int_distribution<
unsigned> distribution(
static_cast<
unsigned>(states::start),
static_cast<
unsigned>(states::end)-1);
292 auto generator=std::bind(distribution, gen);
293 const auto t1=std::chrono::high_resolution_clock::now();
294 for (
unsigned long num_loops=0;num_loops<test_size;++num_loops) {
295 msm.process(
static_cast<states>(generator()), d);
297 const auto t2=std::chrono::high_resolution_clock::now();
298 BOOST_CHECK_GT(d.i, 0);
299 return timed_results_t::value_type(test_size/(
static_cast<
double>(std::chrono::duration_cast<std::chrono::nanoseconds>(t2-t1).count())/1000000000));
302 std::cout<<
typeid(state_machine_t).name()<<
" state-changes/sec="<<timed_results.first<<std::endl;
303 #ifdef JMMCG_PERFORMANCE_TESTS
304 stats_to_csv::handle->stats<<timed_results.first.to_csv()<<std::flush;
305 BOOST_CHECK(!timed_results.second);
309 BOOST_AUTO_TEST_SUITE_END()
311 BOOST_AUTO_TEST_SUITE_END()