OnixS C++ CME MDP Premium Market Data Handler 5.11.1
Users' manual and API documentation
Loading...
Searching...
No Matches
PacketHolder.h
Go to the documentation of this file.
1// Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2//
3// This software owned by Onix Solutions Limited [OnixS] and is
4// protected by copyright law and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable
7// OnixS Software Services Agreement (the Agreement) and Customer end user license
8// agreements granting a non-assignable, non-transferable and non-exclusive license
9// to use the software for it's own data processing purposes under the terms defined
10// in the Agreement.
11//
12// Except as otherwise granted within the terms of the Agreement, copying or
13// reproduction of any part of this source code or associated reference material
14// to any other location for further reproduction or redistribution, and any
15// amendments to this copyright notice, are expressly prohibited.
16//
17// Any reproduction or redistribution for sale or hiring of the Software not in
18// accordance with the terms of the Agreement is a violation of copyright law.
19//
20
21#pragma once
22
23#include <array>
24#include <cstddef>
25#include <ostream>
26#include <string>
27#include <tuple>
28#include <type_traits>
29#include <utility>
30
33
35
66template <typename FirstMessageType = Messaging::AdminHeartbeat12, typename... RemainingMessageTypes>
68{
69 template <typename MessageType>
70 struct Element
71 {
72 using Type = MessageHolder<MessageType>;
73 };
74
75 template <typename MessageType, std::size_t MaxMessageSize>
76 struct Element<MessageHolder<MessageType, MaxMessageSize>>
77 {
79 };
80
81 template <typename>
82 static Messaging::SchemaVersion schemaVersion(Messaging::SchemaVersion version) noexcept
83 {
84 return version;
85 }
86
87 std::tuple<typename Element<FirstMessageType>::Type, typename Element<RemainingMessageTypes>::Type...> messages_;
88
89public:
91 enum : std::size_t { MessageCount = 1 + sizeof...(RemainingMessageTypes) };
92
94 using MessageSpans = std::array<ByteSpan, MessageCount>;
95
98 PacketHolder() = default;
99
104 : messages_(schemaVersion<FirstMessageType>(version), schemaVersion<RemainingMessageTypes>(version)...)
105 {
106 }
107
113 template <std::size_t Index>
114 auto message() noexcept -> decltype(std::get<Index>(messages_))
115 {
116 return std::get<Index>(messages_);
117 }
118
124 template <std::size_t Index>
125 auto message() const noexcept -> decltype(std::get<Index>(messages_))
126 {
127 return std::get<Index>(messages_);
128 }
129
135 template <std::size_t Index>
136 auto get() noexcept -> decltype(std::get<Index>(messages_))
137 {
138 return message<Index>();
139 }
140
146 template <std::size_t Index>
147 auto get() const noexcept -> decltype(std::get<Index>(messages_))
148 {
149 return message<Index>();
150 }
151
163 {
164 MessageSpans result{};
165 fillMessageSpans<0>(result);
166 return result;
167 }
168
169private:
170 PacketHolder(const PacketHolder&) = delete;
171 PacketHolder& operator=(const PacketHolder&) = delete;
172 PacketHolder(PacketHolder&&) = delete;
173 PacketHolder& operator=(PacketHolder&&) = delete;
174
175 template <std::size_t Index>
176 typename std::enable_if<Index == MessageCount>::type fillMessageSpans(MessageSpans&) noexcept
177 {
178 }
179
180 template <std::size_t Index>
181 typename std::enable_if<(Index < MessageCount)>::type fillMessageSpans(MessageSpans& result) noexcept
182 {
183 result[Index] = std::get<Index>(messages_).toNetworkBytes();
184 fillMessageSpans<Index + 1>(result);
185 }
186};
187
195template <std::size_t Index, typename... MessageTypes>
196inline auto get(PacketHolder<MessageTypes...>& holder) noexcept -> decltype(holder.template get<Index>())
197{
198 return holder.template get<Index>();
199}
200
208template <std::size_t Index, typename... MessageTypes>
209inline auto get(const PacketHolder<MessageTypes...>& holder) noexcept -> decltype(holder.template get<Index>())
210{
211 return holder.template get<Index>();
212}
213
214namespace details {
215
217template <std::size_t Index, typename... MessageTypes>
218typename std::enable_if<Index == PacketHolder<MessageTypes...>::MessageCount>::type appendPacketHolderMessages(
219 std::string&, const PacketHolder<MessageTypes...>&)
220{
221}
222
224template <std::size_t Index, typename... MessageTypes>
225typename std::enable_if<(Index < PacketHolder<MessageTypes...>::MessageCount)>::type appendPacketHolderMessages(
226 std::string& str, const PacketHolder<MessageTypes...>& holder)
227{
228 if (Index != 0)
229 str += ", ";
230
231 toStr(str, holder.template message<Index>());
232 appendPacketHolderMessages<Index + 1>(str, holder);
233}
234
235} // namespace details
236
242template <typename... MessageTypes>
243inline void toStr(std::string& str, const PacketHolder<MessageTypes...>& holder)
244{
245 str += "PacketHolder[Messages=[";
246 details::appendPacketHolderMessages<0>(str, holder);
247 str += "]]";
248}
249
255template <typename... MessageTypes>
257{
258 std::string result;
259 toStr(result, holder);
260 return result;
261}
262
269template <typename... MessageTypes>
270inline std::ostream& operator<<(std::ostream& stream, const PacketHolder<MessageTypes...>& holder)
271{
272 return stream << toStr(holder);
273}
274
276
277namespace std {
278
281template <typename... MessageTypes>
282struct tuple_size<ONIXS_CME_MDH_TESTING_NAMESPACE::PacketHolder<MessageTypes...>>
283 : integral_constant<size_t, ONIXS_CME_MDH_TESTING_NAMESPACE::PacketHolder<MessageTypes...>::MessageCount>
284{
285};
286
290template <size_t Index, typename... MessageTypes>
291struct tuple_element<Index, ONIXS_CME_MDH_TESTING_NAMESPACE::PacketHolder<MessageTypes...>>
292{
293 using type = typename remove_reference<decltype(
294 declval<ONIXS_CME_MDH_TESTING_NAMESPACE::PacketHolder<MessageTypes...>&>().template get<Index>())>::type;
295};
296
297} // namespace std
#define ONIXS_CME_MDH_TESTING_NAMESPACE
Definition Bootstrap.h:92
#define ONIXS_CME_MDH_TESTING_NAMESPACE_END
Definition Bootstrap.h:84
#define ONIXS_CME_MDH_TESTING_NAMESPACE_BEGIN
Definition Bootstrap.h:83
#define ONIXS_CMEMDH_NODISCARD
Definition Compiler.h:165
Owns fixed-capacity storage for a prefixed CME message.
Owns a fixed set of CME message holders for sending in one packet.
PacketHolder(Messaging::SchemaVersion version)
Constructs all held messages for a common schema version.
MessageSpans toNetworkMessageSpans() noexcept
Commits every message prefix and returns network-ready byte views.
auto message() const noexcept -> decltype(std::get< Index >(messages_))
Returns read-only indexed access to a stored message holder.
PacketHolder()=default
Constructs each held message using its default schema version.
auto get() noexcept -> decltype(std::get< Index >(messages_))
Returns mutable tuple-style indexed access to a stored message holder.
auto get() const noexcept -> decltype(std::get< Index >(messages_))
Returns read-only tuple-style indexed access to a stored message holder.
auto message() noexcept -> decltype(std::get< Index >(messages_))
Returns mutable indexed access to a stored message holder.
std::array< ByteSpan, MessageCount > MessageSpans
Fixed-size array of read-only byte views, one per held message.
MessageHeader::Version SchemaVersion
Aliases SBE-encoded data version type.
auto get(PacketHolder< MessageTypes... > &holder) noexcept -> decltype(holder.template get< Index >())
Returns mutable tuple-style indexed access to a stored message holder.
void toStr(std::string &str, const MessageHolder< MessageType, MaxMessageSize > &holder)
Appends the holder's capacity, prefix, and message to a string.
std::ostream & operator<<(std::ostream &stream, const MessageHolder< MessageType, MaxMessageSize > &rhs)
Writes the holder's capacity, prefix, and message to a stream.
STL namespace.
typename remove_reference< decltype( declval< OnixS::CME::MDH::Test::PacketHolder< MessageTypes... > & >().template get< Index >())>::type type