This source file includes following definitions.
- decltype
- decltype
1 #ifndef libjmmcg_isimud_exchanges_common_processing_rules_hpp
2 #define libjmmcg_isimud_exchanges_common_processing_rules_hpp
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <boost/mpl/front.hpp>
25 #include <boost/mpl/pop_front.hpp>
26
27 #include <map>
28
29 namespace isimud { namespace exchanges { namespace common {
30
31
32
33
34
35
36 template<class SrcMsgDetails, class DestMsgDetails, class Derived, class FlowMsgTypes, class SktT>
37 class message_responses {
38 public:
39
40 using src_msg_details_t=SrcMsgDetails;
41
42 using dest_msg_details_t=DestMsgDetails;
43 using derived_t=Derived;
44 using flow_msg_types=FlowMsgTypes;
45 using socket_t=SktT;
46
47 protected:
48
49 template<class OutMsg>
50 struct just_send_to_exchg {
51 using dest_msg_t=OutMsg;
52
53 template<class ...Args>
54 explicit constexpr just_send_to_exchg(Args &&...) noexcept(true) {}
55
56
57
58
59
60 template<auto state, auto next>
61 decltype(next)
62 operator()(typename src_msg_details_t::msg_buffer_t const &, socket_t &exchg_skt, socket_t &) const {
63 exchg_skt.write(dest_msg_t());
64 return next;
65 }
66 };
67
68 template<class InMsg, class OutMsg>
69 struct convert_then_send {
70 using src_msg_t=InMsg;
71 using dest_msg_t=OutMsg;
72
73 template<class ...Args>
74 explicit constexpr convert_then_send(Args &&...) noexcept(true) {}
75
76
77
78
79
80
81 template<auto state, auto next>
82 decltype(next)
83 operator()(typename src_msg_details_t::msg_buffer_t const &buff, socket_t &, socket_t &client_skt) const {
84 src_msg_t const &msg=reinterpret_cast<src_msg_t const &>(buff);
85 assert(msg.type()==state);
86 client_skt.write(dest_msg_t(msg));
87 return next;
88 }
89 };
90
91 template<class InMsg, class OutMsg>
92 class convert_then_send_ref_data {
93 public:
94 using src_msg_t=InMsg;
95 using dest_msg_t=OutMsg;
96 using ref_data_t=typename dest_msg_details_t::ref_data_t;
97
98 explicit convert_then_send_ref_data(ref_data_t &rd) noexcept(true)
99 : ref_data_(rd) {}
100 constexpr convert_then_send_ref_data(convert_then_send_ref_data const &v) noexcept(true)
101 : ref_data_(v.ref_data_) {}
102
103
104
105
106
107
108 template<auto state, auto next>
109 decltype(next)
110 operator()(typename src_msg_details_t::msg_buffer_t const &buff, socket_t &, socket_t &client_skt) const {
111 src_msg_t const &msg=reinterpret_cast<src_msg_t const &>(buff);
112 assert(msg.type()==state);
113 client_skt.write(dest_msg_t(msg, ref_data_));
114 return next;
115 }
116
117 private:
118 ref_data_t &ref_data_;
119 };
120
121 template<class InMsg, class OutMsg>
122 class convert_then_send_seq_num {
123 public:
124 using src_msg_t=InMsg;
125 using dest_msg_t=OutMsg;
126 using ref_data_t=typename dest_msg_details_t::ref_data_t;
127
128 explicit convert_then_send_seq_num(std::uint32_t &sq) noexcept(true)
129 : sequenceNumber(sq) {}
130 constexpr convert_then_send_seq_num(convert_then_send_seq_num const &v) noexcept(true)
131 : sequenceNumber(v.sequenceNumber) {}
132
133
134
135
136
137
138 template<auto state, auto next>
139 decltype(next)
140 operator()(typename src_msg_details_t::msg_buffer_t const &buff, socket_t &, socket_t &client_skt) const {
141 src_msg_t const &msg=reinterpret_cast<src_msg_t const &>(buff);
142 assert(msg.type()==state);
143 client_skt.write(dest_msg_t(msg, sequenceNumber));
144 return next;
145 }
146
147 private:
148 std::uint32_t &sequenceNumber;
149 };
150 template<class OutMsg, bool ToClient>
151 struct send_reject {
152 using dest_msg_t=OutMsg;
153
154 template<class ...Args>
155 explicit constexpr send_reject(Args &&...) noexcept(true) {}
156
157
158
159
160
161 template<auto state, auto next>
162 decltype(next)
163 operator()(typename src_msg_details_t::msg_buffer_t const &, socket_t &exchg_skt, socket_t &client_skt) const {
164 if constexpr (ToClient) {
165 client_skt.write(dest_msg_t(dest_msg_t::unknown_msg));
166 } else {
167 exchg_skt.write(dest_msg_t(dest_msg_t::unknown_msg));
168 }
169 return next;
170 }
171 };
172
173
174
175
176 virtual bool process_msg(typename src_msg_details_t::msg_buffer_t const &buff, socket_t &exchg_skt, socket_t &client_skt)=0;
177 };
178
179
180
181
182
183
184
185 template<class MsgDetails, class Derived, class SktT>
186 class simulator_responses : public message_responses<MsgDetails, MsgDetails, Derived, typename MsgDetails::client_to_exchange_messages_t, SktT> {
187 public:
188 using base_t=message_responses<MsgDetails, MsgDetails, Derived, typename MsgDetails::client_to_exchange_messages_t, SktT>;
189 using msg_details_t=typename base_t::src_msg_details_t;
190 using src_msg_details_t=msg_details_t;
191 using socket_t=typename base_t::socket_t;
192 using derived_t=typename base_t::derived_t;
193 using base_t::convert_then_send;
194 using base_t::convert_then_send_ref_data;
195 using base_t::send_reject;
196 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;
197
198
199 static inline constexpr typename msg_details_t::UserName_t username{"usr"};
200
201 static inline constexpr typename msg_details_t::Password_t password{"fubar"};
202
203 static inline constexpr typename msg_details_t::Password_t new_password{"snafu"};
204
205
206
207
208 static inline constexpr std::int32_t quantity_limit=100;
209
210 static inline constexpr Price_t price=42;
211
212 static inline constexpr Price_t scaled_price=42*msg_details_t::implied_decimal_places;
213
214
215
216
217 virtual bool process_msg(typename src_msg_details_t::msg_buffer_t const &buff, socket_t &exchg_skt, socket_t &client_skt)=0;
218
219 std::string to_string() const noexcept(false);
220
221 protected:
222 using order_book_t=std::map<typename msg_details_t::ClientOrderID_t, typename msg_details_t::NewOrder>;
223 order_book_t order_book;
224 std::int32_t sequenceNumber{};
225
226 simulator_responses()=default;
227 simulator_responses(simulator_responses const &)=default;
228 };
229
230 template<class MsgDetails, class Derived, class SktT> inline std::ostream &
231 operator<<(std::ostream &os, simulator_responses<MsgDetails, Derived, SktT> const &ec) noexcept(false);
232
233 } } }
234
235 #include "processing_rules_impl.hpp"
236
237 #endif