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 &