libjmmcg  release_579_6_g8cffd
A C++ library containing an eclectic mix of useful, advanced components.
mit_msm.cpp
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright © 2018 by J.M.McGuiness, isimud@hussar.me.uk
3 **
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Lesser General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2.1 of the License, or (at your option) any later version.
8 **
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Lesser General Public License for more details.
13 **
14 ** You should have received a copy of the GNU Lesser General Public
15 ** License along with this library; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 
19 #include "stdafx.h"
20 
21 #define BOOST_TEST_MODULE isimud_tests
22 #include <boost/test/included/unit_test.hpp>
23 
24 #include <boost/mpl/list.hpp>
25 
26 #include "../exchanges/FIX/v5.0sp2/fix.hpp"
27 #include "../exchanges/MIT/BIT/messages.hpp"
28 /* TODO #include "../exchanges/MIT/JSE/messages.hpp"
29 #include "../exchanges/MIT/LSE/messages.hpp"
30 #include "../exchanges/MIT/OSLO/messages.hpp"
31 #include "../exchanges/MIT/TRQ/messages.hpp"
32 */
33 #include "core/msm.hpp"
34 
35 using namespace libjmmcg;
36 using namespace libisimud;
37 
38 using msg_types=boost::mpl::list<
39  exchanges::MIT::BIT::MsgTypes/* TODO,
40  exchanges::MIT::JSE::MsgTypes,
41  exchanges::MIT::LSE::MsgTypes,
42  exchanges::MIT::OSLO::MsgTypes,
43  exchanges::MIT::TRQ::MsgTypes*/
44 >;
45 
46 template<class DestMsgsT>
47 struct data_with_payload {
48  using dest_msg_details_t=DestMsgsT;
49  typename dest_msg_details_t::MsgTypes_t state{};
50  unsigned j{68};
51 };
52 
53 template<
54  class SrcMsgsT,
55  class DestMsgsT,
56  template<class> class MSMType,
57  template<class, class> class MSMRowsType,
58  template<class> class MachineT
59 >
61  using src_msg_details_t=SrcMsgsT;
62  using dest_msg_details_t=DestMsgsT;
63  template<class StateMachineT> using msm_t=MSMType<StateMachineT>;
64  struct fn_event {
65  using argument_type=data_with_payload<dest_msg_details_t>;
66 
67  explicit fn_event(unsigned &j)
68  : j_(j) {}
69 
70  template<auto state, auto next>
71  void operator()(argument_type &p) const noexcept(true) {
72  p.state=next;
73  p.j+=j_;
74  }
75 
76  private:
77  unsigned &j_;
78  };
79 
80  struct state_machine_t final : msm_t<state_machine_t> {
81  using base_t=msm_t<state_machine_t>;
82  using row_t=MSMRowsType<typename src_msg_details_t::MsgType_t, typename dest_msg_details_t::MsgTypes_t>;
83  using transition_table=typename base_t::template rows<
84  typename row_t::template row<
85  src_msg_details_t::NewOrder_t::static_type,
86  fn_event,
87  dest_msg_details_t::NewOrder_t::static_type
88  >,
89  typename row_t::template row<
90  src_msg_details_t::OrderCancelRequest::static_type,
91  fn_event,
92  dest_msg_details_t::OrderCancelRequest::static_type
93  >,
94  typename row_t::template row<
95  src_msg_details_t::OrderCancelReplace::static_type,
96  fn_event,
97  dest_msg_details_t::OrderCancelReplaceRequest::static_type
98  >/* This next row breaks g++ v9.1.0... ,
99  typename row_t::template row<
100  src_msg_details_t::MatchAll,
101  fn_event,
102  dest_msg_details_t::Reject::static_type
103  >*/
104  >;
105  };
106  using machine=MachineT<state_machine_t>;
107 
109  : j(42), msm(j, j, j) {
110  }
111 
112  void process(typename src_msg_details_t::MsgType_t state, data_with_payload<dest_msg_details_t> &p) noexcept(false) {
113  msm.process(state, p);
114  }
115 
116  unsigned j;
117  machine msm;
118 };
119 
120 BOOST_AUTO_TEST_SUITE(isimud)
121 
122 BOOST_AUTO_TEST_SUITE(msm_tests)
123 
124 BOOST_AUTO_TEST_SUITE(unroll)
125 
126 BOOST_AUTO_TEST_CASE_TEMPLATE(start_state_assign_msm_states, msg, msg_types) {
127  using assign_msm_states_t=assign_msm_states<
128  exchanges::FIX::v5_0sp2::MsgTypes,
129  msg,
130  msm::unroll::state_transition_table,
131  msm::unroll::row_types,
132  msm::unroll::machine
133  >;
134  assign_msm_states_t msm;
135  data_with_payload<msg> d;
136  BOOST_CHECK_NO_THROW(msm.process(exchanges::FIX::v5_0sp2::MsgTypes::NewOrder_t::static_type, d));
137  BOOST_CHECK_EQUAL(d.j, 68+42);
138 }
139 
140 BOOST_AUTO_TEST_SUITE_END()
141 
142 BOOST_AUTO_TEST_SUITE(hash)
143 
144 BOOST_AUTO_TEST_CASE_TEMPLATE(start_state_assign_msm_states, msg, msg_types) {
145  using assign_msm_states_t=assign_msm_states<
146  exchanges::FIX::v5_0sp2::MsgTypes,
147  msg,
148  msm::hash::state_transition_table,
149  msm::hash::row_types,
150  msm::hash::machine
151  >;
152  assign_msm_states_t msm;
153  data_with_payload<msg> d;
154  BOOST_CHECK_NO_THROW(msm.process(exchanges::FIX::v5_0sp2::MsgTypes::NewOrder_t::static_type, d));
155  BOOST_CHECK_EQUAL(d.state, assign_msm_states_t::dest_msg_details_t::NewOrder_t::static_type);
156  BOOST_CHECK_EQUAL(d.j, 68+42);
157 }
158 
159 BOOST_AUTO_TEST_SUITE_END()
160 
161 BOOST_AUTO_TEST_SUITE_END()
162 
163 BOOST_AUTO_TEST_SUITE_END()