-
Notifications
You must be signed in to change notification settings - Fork 0
/
io.hpp
146 lines (125 loc) · 3.18 KB
/
io.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
// This file contains definitions used by the provided I/O code.
// There should be no need to modify this file.
#pragma once
#include <mutex>
#include <utility>
#include <cstdint>
#include <iostream>
enum CommandType
{
input_buy = 'B',
input_sell = 'S',
input_cancel = 'C'
};
struct ClientCommand
{
CommandType type;
uint32_t order_id;
uint32_t price;
uint32_t count;
char instrument[9];
};
enum class ReadResult
{
Success,
EndOfFile,
Error
};
struct ClientConnection
{
~ClientConnection() { this->freeHandle(); }
explicit ClientConnection(int handle) : m_handle(handle) { }
ClientConnection(ClientConnection&& other) : m_handle(std::exchange(other.m_handle, -1)) { }
ClientConnection& operator=(ClientConnection&& other)
{
if(&other == this)
return *this;
this->freeHandle();
m_handle = std::exchange(other.m_handle, -1);
return *this;
}
ClientConnection(const ClientConnection&) = delete;
ClientConnection& operator=(const ClientConnection&) = delete;
ReadResult readInput(ClientCommand& read_into);
private:
int m_handle;
void freeHandle();
};
// An implementation of std::osyncstream{std::cout}
// std::osyncstream would work but badly supported right now
struct SyncCout
{
static std::mutex mut;
std::scoped_lock<std::mutex> lock { SyncCout::mut };
template <typename T>
friend const SyncCout& operator<<(const SyncCout& s, T&& v)
{
std::cout << std::forward<T>(v);
return s;
}
friend const SyncCout& operator<<(const SyncCout& s, std::ostream& (*f)(std::ostream&) )
{
std::cout << f;
return s;
}
};
// An implementation of std::osyncstream{std::cerr}
// std::osyncstream would work but badly supported right now
struct SyncCerr
{
static std::mutex mut;
std::scoped_lock<std::mutex> lock { SyncCerr::mut };
template <typename T>
friend const SyncCerr& operator<<(const SyncCerr& s, T&& v)
{
std::cerr << std::forward<T>(v);
return s;
}
friend const SyncCerr& operator<<(const SyncCerr& s, std::ostream& (*f)(std::ostream&) )
{
std::cerr << f;
return s;
}
};
class Output
{
public:
inline static void
OrderAdded(uint32_t id, const char* symbol, uint32_t price, uint32_t count, bool is_sell_side, intmax_t output_timestamp)
{
SyncCout()
<< (is_sell_side ? "S " : "B ") //
<< id << " " //
<< symbol << " " //
<< price << " " //
<< count << " " //
<< output_timestamp //
<< std::endl;
}
inline static void OrderExecuted(uint32_t resting_id,
uint32_t new_id,
uint32_t execution_id,
uint32_t price,
uint32_t count,
intmax_t output_timestamp)
{
SyncCout()
<< "E " //
<< resting_id << " " //
<< new_id << " " //
<< execution_id << " " //
<< price << " " //
<< count << " " //
<< output_timestamp //
<< std::endl;
}
inline static void OrderDeleted(uint32_t id, bool cancel_accepted, intmax_t output_timestamp)
{
SyncCout()
<< "X " //
<< id << " " //
<< (cancel_accepted ? "A " : "R ") //
<< output_timestamp //
<< std::endl;
}
};