1 #ifndef ISIMUD_EXCHANGES_COMMON_PROCESSING_RULES_HPP
2 #define ISIMUD_EXCHANGES_COMMON_PROCESSING_RULES_HPP
22 #include <boost/mpl/front.hpp>
23 #include <boost/mpl/pop_front.hpp>
34 template<
class SrcMsgDetails,
class DestMsgDetails,
class Derived,
class FlowMsgTypes>
38 using src_msg_details_t=SrcMsgDetails;
40 using dest_msg_details_t=DestMsgDetails;
41 using derived_t=Derived;
42 using flow_msg_types=FlowMsgTypes;
46 template<
class OutMsg>
48 using dest_msg_t=OutMsg;
50 template<
class ...Args>
57 template<
auto state,
auto next,
class SktT,
class ClientCxn>
59 operator()(
typename src_msg_details_t::msg_buffer_t
const &, SktT &exchg_skt, ClientCxn &)
const {
60 exchg_skt.write(dest_msg_t());
65 template<
class InMsg,
class OutMsg>
67 using src_msg_t=InMsg;
68 using dest_msg_t=OutMsg;
70 template<
class ...Args>
78 template<
auto state,
auto next,
class SktT,
class ClientCxn>
80 operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &, ClientCxn &client_cxn)
const {
82 src_msg_t
const &msg=
reinterpret_cast<src_msg_t
const &>(buff);
83 assert(
static_cast<
typename src_msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename src_msg_details_t::MsgTypes_t>(state));
84 client_cxn->socket().write(dest_msg_t(msg));
89 template<
class InMsg,
class OutMsg>
92 using src_msg_t=InMsg;
93 using dest_msg_t=OutMsg;
94 using ref_data=
typename dest_msg_details_t::ref_data;
99 : ref_data_(v.ref_data_) {}
106 template<
auto state,
auto next,
class SktT,
class ClientCxn>
108 operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &, ClientCxn &client_skt)
const {
109 src_msg_t
const &msg=
reinterpret_cast<src_msg_t
const &>(buff);
110 assert(msg.type()==state);
111 client_skt.write(dest_msg_t(msg, ref_data_));
116 ref_data
const &ref_data_;
119 template<
class InMsg,
class OutMsg,
bool ToClient=
true>
122 using src_msg_t=InMsg;
123 using dest_msg_t=OutMsg;
126 : sequenceNumber(sq) {}
129 : sequenceNumber(
std::get<0>(a)) {}
131 : sequenceNumber(v.sequenceNumber) {}
138 template<
auto state,
auto next,
class SktT>
140 operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, SktT &client_skt)
const {
141 src_msg_t
const &msg=
reinterpret_cast<src_msg_t
const &>(buff);
142 assert(
static_cast<
typename src_msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename src_msg_details_t::MsgTypes_t>(state));
143 if constexpr (ToClient) {
144 client_skt.write(dest_msg_t(msg, sequenceNumber));
146 exchg_skt.write(dest_msg_t(sequenceNumber));
155 template<
auto state,
auto next,
class SktT,
class ClientCxn>
157 operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, ClientCxn &client_cxn)
const {
158 src_msg_t
const &msg=
reinterpret_cast<src_msg_t
const &>(buff);
159 assert(
static_cast<
typename src_msg_details_t::MsgTypes_t>(msg.type())==
static_cast<
typename src_msg_details_t::MsgTypes_t>(state));
160 if constexpr (ToClient) {
162 client_cxn.socket().write(dest_msg_t(msg, sequenceNumber));
164 exchg_skt.write(dest_msg_t(sequenceNumber));
170 typename dest_msg_details_t::SeqNum_t &sequenceNumber;
172 template<
class OutMsg,
bool ToClient>
174 using dest_msg_t=OutMsg;
176 template<
class ...Args>
183 template<
auto state,
auto next,
class SktT>
185 operator()(
typename src_msg_details_t::msg_buffer_t
const &, SktT &exchg_skt, SktT &client_skt)
const {
186 if constexpr (ToClient) {
187 client_skt.write(dest_msg_t(dest_msg_t::unknown_msg));
189 exchg_skt.write(dest_msg_t(dest_msg_t::unknown_msg));
193 template<
auto state,
auto next,
class SktT,
class ClientCxn>
195 operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, ClientCxn &client_cxn)
const {
196 return operator()<state, next>(buff, exchg_skt, client_cxn->socket());
203 : business_msm(msm) {}
205 : business_msm(
std::get<1>(a)) {}
211 template<
auto state,
auto next,
class SktT,
class ClientCxn>
212 auto operator()(
typename src_msg_details_t::msg_buffer_t
const &buff, SktT &exchg_skt, ClientCxn &client_cxn)
const noexcept(
false) {
214 while (!client_cxn) {
215 std::this_thread::yield();
217 assert(client_cxn->socket().is_open());
218 typename src_msg_details_t::Header_t
const &hdr=
reinterpret_cast<
typename src_msg_details_t::Header_t
const &>(buff);
219 const auto next_from_business=business_msm.process(
static_cast<
typename src_msg_details_t::MsgTypes_t>(hdr.type()), buff, exchg_skt, client_cxn);
220 return next_from_business;
224 MSM
const &business_msm;
234 template<
class MsgDetails,
class Derived>
237 using base_t=
message_responses<MsgDetails, MsgDetails, Derived,
typename MsgDetails::client_to_exchange_messages_t>;
238 using msg_details_t=
typename base_t::src_msg_details_t;
239 using src_msg_details_t=msg_details_t;
240 using derived_t=
typename base_t::derived_t;
241 using base_t::convert_then_send;
242 using base_t::convert_then_send_ref_data;
243 using base_t::send_reject;
244 using Price_t=
typename std::conditional<
std::is_integral<
typename msg_details_t::Price_t>::value,
typename msg_details_t::Price_t,
std::uint64_t>::type;
258 static inline constexpr Price_t
price=42;
260 static inline constexpr Price_t
scaled_price=42*msg_details_t::implied_decimal_places;
261 BOOST_MPL_ASSERT_RELATION(scaled_price, >, 0);
274 template<
class MsgDetails,
class Derived>
inline std::ostream &