OnixS C++ CME MDP Premium Market Data Handler 5.11.1
Users' manual and API documentation
Loading...
Searching...
No Matches
DataFeed.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 protected by copyright law
4// and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable OnixS Software
7// Services Agreement (the Agreement) and Customer end user license agreements granting
8// a non-assignable, non-transferable and non-exclusive license to use the software
9// for it's own data processing purposes under the terms defined in the Agreement.
10//
11// Except as otherwise granted within the terms of the Agreement, copying or reproduction of any part
12// of this source code or associated reference material to any other location for further reproduction
13// or redistribution, and any amendments to this copyright notice, are expressly prohibited.
14//
15// Any reproduction or redistribution for sale or hiring of the Software not in accordance with
16// the terms of the Agreement is a violation of copyright law.
17//
18
19#pragma once
20
21#include <array>
22#include <type_traits>
23#include <utility>
24#include <cstddef>
25
27#include <OnixS/CME/MDH/Watch.h>
32
34
36namespace details
37{
38 template <typename Feed, typename... Arguments>
39 struct IsDataFeedSelfConstruction : std::false_type{};
40
41 template <typename Feed, typename Argument>
42 struct IsDataFeedSelfConstruction<Feed, Argument>
43 : std::is_base_of<Feed, typename std::decay<Argument>::type>{};
44
45 template <typename Message>
47 {
48 private:
49 template <typename T>
50 static auto test(int) -> decltype(asSpan(std::declval<T>()), std::true_type{});
51
52 template <typename>
53 static std::false_type test(...);
54
55 public:
56 static constexpr bool value = decltype(test<Message>(0))::value;
57 };
58
59 template <typename Message>
60 struct IsMaterializableMessage : std::integral_constant<bool,
61 IsMessageRecipe<typename std::decay<Message>::type>::value ||
62 IsSpanCompatibleMessage<Message>::value>
63 {};
64
65 template <typename Message, bool = IsMessageRecipe<typename std::decay<Message>::type>::value>
67 {
68 public:
69 explicit MaterializedMessage(Message&& message) noexcept
70 : message_(std::forward<Message>(message))
71 {
72 }
73
75 {
76 return asSpan(std::forward<Message>(message_));
77 }
78
79 private:
80 Message&& message_;
81 };
82
83 template <typename Message>
84 class MaterializedMessage<Message, true>
85 {
86 using Recipe = typename std::decay<Message>::type;
87
88 public:
89 explicit MaterializedMessage(const Recipe& recipe)
90 {
91 recipe.applyTo(holder_);
92 }
93
94 ByteSpan span() noexcept
95 {
96 return asSpan(holder_);
97 }
98
99 private:
100 typename Recipe::HolderType holder_;
101 };
102}
103
130template <typename Delivery>
131class DataFeed : private Delivery
132{
133 template <bool...> struct BooleanPack{};
134 template <bool... Values> using All = std::is_same<BooleanPack<Values..., true>, BooleanPack<true, Values...>>;
135
136protected:
137 enum : std::size_t { SendMaxSpansCount = Delivery::MaxSpansCount };
138
141 template <typename... Messages>
142 using MessageSpans = std::array<ByteSpan, sizeof...(Messages)>;
143
147 template <typename Result, typename... Messages>
148 using EnableSend = typename std::enable_if<
149 (sizeof...(Messages) > 0)
150 && (sizeof...(Messages) < SendMaxSpansCount)
151 && All<!std::is_base_of<PacketHeader, typename std::decay<Messages>::type>::value...>::value
152 && All<details::IsMaterializableMessage<Messages>::value...>::value,
153 Result>::type;
154
158 template <typename Result, typename... Messages>
159 using EnablePacketHolderSend = typename std::enable_if<(sizeof...(Messages) < SendMaxSpansCount), Result>::type;
160
161public:
163 enum : std::size_t { MaxSpansCount = Delivery::MaxSpansCount };
164 static_assert(MaxSpansCount >= 2, "must include the packet header and at least one message.");
165
170 template <typename... Arguments, typename std::enable_if<
171 !details::IsDataFeedSelfConstruction<DataFeed, Arguments...>::value, int>::type = 0>
172 explicit DataFeed(Arguments&&... arguments)
173 : Delivery(std::forward<Arguments>(arguments)...)
174 {
175 }
176
178 virtual ~DataFeed() = default;
179
198 template <typename... Messages>
200 auto send(SequenceNumber seqNum, Messages&&... messages) -> EnableSend<Threading::Event, Messages...>
201 {
202 validateMessageCount<Messages...>();
203 MessageSpans<Messages...> messageSpans{};
204 SendMessages consumer{*this, seqNum, Messaging::Timestamp{}, true};
205 return materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
206 }
207
215 template <typename... Messages>
217 auto send(
218 SequenceNumber seqNum, Messaging::Timestamp sendingTime,
219 Messages&&... messages) -> EnableSend<Threading::Event, Messages...>
220 {
221 validateMessageCount<Messages...>();
222 MessageSpans<Messages...> messageSpans{};
223 SendMessages consumer{*this, seqNum, sendingTime, false};
224 return materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
225 }
226
246 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
248 Threading::Event send(SequenceNumber seqNum, Collection&& messages)
249 {
250 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
251 return send(seqNum, UtcWatch::now(), checked.data, checked.count);
252 }
253
261 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
263 Threading::Event send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection&& messages)
264 {
265 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
266 return send(seqNum, sendingTime, checked.data, checked.count);
267 }
268
282 template <typename... Messages>
286 {
287 return sendPacketHolder(seqNum, packet);
288 }
289
297 template <typename... Messages>
301 {
302 return sendPacketHolder(seqNum, sendingTime, packet);
303 }
304
319 template <typename... Messages>
323 {
324 return sendPacketHolder(seqNum, packet);
325 }
326
334 template <typename... Messages>
338 {
339 return sendPacketHolder(seqNum, sendingTime, packet);
340 }
341
358 template <typename... Messages>
359 auto sendPrimary(SequenceNumber seqNum, Messages&&... messages) -> EnableSend<void, Messages...>
360 {
361 validateMessageCount<Messages...>();
362 MessageSpans<Messages...> messageSpans{};
363 SendPrimaryMessages consumer{*this, seqNum, Messaging::Timestamp{}, true};
364 materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
365 }
366
373 template <typename... Messages>
374 auto sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Messages&&... messages)
375 -> EnableSend<void, Messages...>
376 {
377 validateMessageCount<Messages...>();
378 MessageSpans<Messages...> messageSpans{};
379 SendPrimaryMessages consumer{*this, seqNum, sendingTime, false};
380 materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
381 }
382
399 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
400 void sendPrimary(SequenceNumber seqNum, Collection&& messages)
401 {
402 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
403 sendPrimary(seqNum, UtcWatch::now(), checked.data, checked.count);
404 }
405
412 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
413 void sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection&& messages)
414 {
415 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
416 sendPrimary(seqNum, sendingTime, checked.data, checked.count);
417 }
418
430 template <typename... Messages>
432 -> EnablePacketHolderSend<void, Messages...>
433 {
434 sendPrimaryPacketHolder(seqNum, packet);
435 }
436
443 template <typename... Messages>
445 -> EnablePacketHolderSend<void, Messages...>
446 {
447 sendPrimaryPacketHolder(seqNum, sendingTime, packet);
448 }
449
463 template <typename... Messages>
465 -> EnablePacketHolderSend<void, Messages...>
466 {
467 sendPrimaryPacketHolder(seqNum, packet);
468 }
469
476 template <typename... Messages>
478 -> EnablePacketHolderSend<void, Messages...>
479 {
480 sendPrimaryPacketHolder(seqNum, sendingTime, packet);
481 }
482
499 template <typename... Messages>
500 auto sendSecondary(SequenceNumber seqNum, Messages&&... messages) -> EnableSend<void, Messages...>
501 {
502 validateMessageCount<Messages...>();
503 MessageSpans<Messages...> messageSpans{};
504 SendSecondaryMessages consumer{*this, seqNum, Messaging::Timestamp{}, true};
505 materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
506 }
507
514 template <typename... Messages>
515 auto sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Messages&&... messages)
516 -> EnableSend<void, Messages...>
517 {
518 validateMessageCount<Messages...>();
519 MessageSpans<Messages...> messageSpans{};
520 SendSecondaryMessages consumer{*this, seqNum, sendingTime, false};
521 materializeMessages<0>(consumer, messageSpans, std::forward<Messages>(messages)...);
522 }
523
540 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
541 void sendSecondary(SequenceNumber seqNum, Collection&& messages)
542 {
543 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
544 sendSecondary(seqNum, UtcWatch::now(), checked.data, checked.count);
545 }
546
553 template <class Collection, details::EnableIfByteSpanCollection<Collection> = 0>
554 void sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection&& messages)
555 {
556 const auto checked = details::checkedSpans(messages, MaxSpansCount - 1, 1);
557 sendSecondary(seqNum, sendingTime, checked.data, checked.count);
558 }
559
571 template <typename... Messages>
573 -> EnablePacketHolderSend<void, Messages...>
574 {
575 sendSecondaryPacketHolder(seqNum, packet);
576 }
577
584 template <typename... Messages>
586 -> EnablePacketHolderSend<void, Messages...>
587 {
588 sendSecondaryPacketHolder(seqNum, sendingTime, packet);
589 }
590
604 template <typename... Messages>
606 -> EnablePacketHolderSend<void, Messages...>
607 {
608 sendSecondaryPacketHolder(seqNum, packet);
609 }
610
617 template <typename... Messages>
619 -> EnablePacketHolderSend<void, Messages...>
620 {
621 sendSecondaryPacketHolder(seqNum, sendingTime, packet);
622 }
623
628 {
629 return Delivery::primaryFeed();
630 }
631
636 {
637 return Delivery::secondaryFeed();
638 }
639
643 bool hasSecondary() const noexcept
644 {
645 return Delivery::hasSecondary();
646 }
647
648private:
649 DataFeed(const DataFeed&) = delete;
650 DataFeed& operator=(const DataFeed&) = delete;
651 DataFeed(DataFeed&&) = delete;
652 DataFeed& operator=(DataFeed&&) = delete;
653
654 struct SendMessages
655 {
656 using Result = Threading::Event;
657
658 DataFeed& feed;
659 SequenceNumber sequenceNumber;
660 Messaging::Timestamp sendingTime;
661 bool useCurrentTime;
662
663 Threading::Event operator()(const ByteSpan* spans, size_t count) const
664 {
665 return feed.send(
666 sequenceNumber, useCurrentTime ? UtcWatch::now() : sendingTime,
667 spans, count);
668 }
669 };
670
671 struct SendPrimaryMessages
672 {
673 using Result = void;
674
675 DataFeed& feed;
676 SequenceNumber sequenceNumber;
677 Messaging::Timestamp sendingTime;
678 bool useCurrentTime;
679
680 void operator()(const ByteSpan* spans, size_t count) const
681 {
682 feed.sendPrimary(sequenceNumber, useCurrentTime ? UtcWatch::now() : sendingTime, spans, count);
683 }
684 };
685
686 struct SendSecondaryMessages
687 {
688 using Result = void;
689
690 DataFeed& feed;
691 SequenceNumber sequenceNumber;
692 Messaging::Timestamp sendingTime;
693 bool useCurrentTime;
694
695 void operator()(const ByteSpan* spans, size_t count) const
696 {
697 feed.sendSecondary(sequenceNumber, useCurrentTime ? UtcWatch::now() : sendingTime, spans, count);
698 }
699 };
700
701 template <std::size_t Index, typename Consumer, std::size_t Count>
702 static typename std::enable_if<Index == Count, typename Consumer::Result>::type
703 materializeMessages(Consumer& consumer, std::array<ByteSpan, Count>& spans)
704 {
705 return consumer(spans.data(), spans.size());
706 }
707
708 template <std::size_t Index, typename Consumer, std::size_t Count, typename Message, typename... Messages>
709 static typename Consumer::Result
710 materializeMessages(Consumer& consumer, std::array<ByteSpan, Count>& spans, Message&& message, Messages&&... messages)
711 {
712 details::MaterializedMessage<Message> materialized(std::forward<Message>(message));
713 spans[Index] = materialized.span();
714 return materializeMessages<Index + 1>(consumer, spans, std::forward<Messages>(messages)...);
715 }
716
717 template <typename... Messages>
718 Threading::Event sendPacketHolder(SequenceNumber seqNum, PacketHolder<Messages...>& packet)
719 {
720 const auto messageSpans = makeMessageSpans(packet);
721 return send(seqNum, UtcWatch::now(), messageSpans.data(), messageSpans.size());
722 }
723
724 template <typename... Messages>
725 Threading::Event sendPacketHolder(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder<Messages...>& packet)
726 {
727 const auto messageSpans = makeMessageSpans(packet);
728 return send(seqNum, sendingTime, messageSpans.data(), messageSpans.size());
729 }
730
731 template <typename... Messages>
732 void sendPrimaryPacketHolder(SequenceNumber seqNum, PacketHolder<Messages...>& packet)
733 {
734 const auto messageSpans = makeMessageSpans(packet);
735 sendPrimary(seqNum, UtcWatch::now(), messageSpans.data(), messageSpans.size());
736 }
737
738 template <typename... Messages>
739 void sendPrimaryPacketHolder(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder<Messages...>& packet)
740 {
741 const auto messageSpans = makeMessageSpans(packet);
742 sendPrimary(seqNum, sendingTime, messageSpans.data(), messageSpans.size());
743 }
744
745 template <typename... Messages>
746 void sendSecondaryPacketHolder(SequenceNumber seqNum, PacketHolder<Messages...>& packet)
747 {
748 const auto messageSpans = makeMessageSpans(packet);
749 sendSecondary(seqNum, UtcWatch::now(), messageSpans.data(), messageSpans.size());
750 }
751
752 template <typename... Messages>
753 void sendSecondaryPacketHolder(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder<Messages...>& packet)
754 {
755 const auto messageSpans = makeMessageSpans(packet);
756 sendSecondary(seqNum, sendingTime, messageSpans.data(), messageSpans.size());
757 }
758
759 template <typename... Messages>
760 static typename PacketHolder<Messages...>::MessageSpans makeMessageSpans(PacketHolder<Messages...>& packet) noexcept
761 {
762 validateMessageCount<Messages...>();
763 return packet.toNetworkMessageSpans();
764 }
765
766 template <typename... Messages>
767 static void validateMessageCount() noexcept
768 {
769 static_assert(sizeof...(Messages) < MaxSpansCount, "packet contains too many messages.");
770 }
771
772 template <typename Sender>
773 static auto sendPacket(SequenceNumber seqNum, Messaging::Timestamp sendingTime, const ByteSpan messages[], size_t messagesCnt, Sender&& sender)
774 -> decltype(sender(std::declval<const ByteSpan*>(), std::size_t{}))
775 {
776 PacketHeader packetHeader;
777 packetHeader.seqNumber(seqNum);
778 packetHeader.sendingTime(sendingTime);
779
780 std::array<ByteSpan, MaxSpansCount> packet{};
781 packet[0] = asSpan(packetHeader);
782
783 for (std::size_t index = 0; index < messagesCnt; ++index)
784 packet[index + 1] = messages[index];
785
786 return sender(packet.data(), messagesCnt + 1);
787 }
788
789 Threading::Event send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, const ByteSpan messages[], std::size_t messagesCnt)
790 {
791 auto sender =
792 [this](const ByteSpan packet[], std::size_t spansCount) { return Delivery::send(packet, spansCount);};
793
794 return sendPacket(seqNum, sendingTime, messages, messagesCnt, sender);
795 }
796
797 void sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, const ByteSpan messages[], std::size_t messagesCnt)
798 {
799 auto sender =
800 [this](const ByteSpan packet[], std::size_t spansCount) { Delivery::sendPrimary(packet, spansCount);};
801
802 sendPacket(seqNum, sendingTime, messages, messagesCnt, sender);
803 }
804
805 void sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, const ByteSpan messages[], std::size_t messagesCnt)
806 {
807 auto sender =
808 [this](const ByteSpan packet[], std::size_t spansCount) { Delivery::sendSecondary(packet, spansCount);};
809
810 sendPacket(seqNum, sendingTime, messages, messagesCnt, sender);
811 }
812};
813
#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
The time point without the time-zone information.
Definition Time.h:450
Builds CME MDP packets and delegates their delivery to a delivery policy.
Definition DataFeed.h:132
void sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection &&messages)
Sends encoded messages to the secondary feed with an explicit packet sending time.
Definition DataFeed.h:554
auto sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< void, Messages... >
Sends a packet holder to the primary feed with an explicit packet sending time.
Definition DataFeed.h:444
auto sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< void, Messages... >
Sends a temporary packet holder to the primary feed with an explicit packet sending time.
Definition DataFeed.h:477
auto sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< void, Messages... >
Sends a packet holder to the secondary feed with an explicit packet sending time.
Definition DataFeed.h:585
auto send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< Threading::Event, Messages... >
Sends a temporary packet holder's messages with an explicit packet sending time.
Definition DataFeed.h:336
void sendPrimary(SequenceNumber seqNum, Collection &&messages)
Sends a contiguous collection of encoded messages to the primary feed.
Definition DataFeed.h:400
NetFeedRole::Enum secondaryFeed() const noexcept
Returns the secondary feed role reported by the delivery policy.
Definition DataFeed.h:635
auto send(SequenceNumber seqNum, Messages &&... messages) -> EnableSend< Threading::Event, Messages... >
Sends one or more held messages as one packet through the delivery policy.
Definition DataFeed.h:200
Threading::Event send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection &&messages)
Sends a contiguous collection of encoded messages with an explicit packet sending time.
Definition DataFeed.h:263
Threading::Event send(SequenceNumber seqNum, Collection &&messages)
Sends a contiguous collection of encoded messages as one packet.
Definition DataFeed.h:248
NetFeedRole::Enum primaryFeed() const noexcept
Returns the primary feed role reported by the delivery policy.
Definition DataFeed.h:627
bool hasSecondary() const noexcept
Returns whether the delivery policy reports a secondary feed.
Definition DataFeed.h:643
auto send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< Threading::Event, Messages... >
Sends a packet holder's messages with an explicit packet sending time.
Definition DataFeed.h:299
typename std::enable_if<(sizeof...(Messages) > 0) &&(sizeof...(Messages)< SendMaxSpansCount) &&All<!std::is_base_of< PacketHeader, typename std::decay< Messages >::type >::value... >::value &&All< details::IsMaterializableMessage< Messages >::value... >::value, Result >::type EnableSend
Enables a result type for a non-empty materializable message pack.
Definition DataFeed.h:148
auto sendSecondary(SequenceNumber seqNum, Messages &&... messages) -> EnableSend< void, Messages... >
Sends one or more held messages as one packet to the secondary feed.
Definition DataFeed.h:500
void sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Collection &&messages)
Sends encoded messages to the primary feed with an explicit packet sending time.
Definition DataFeed.h:413
auto sendPrimary(SequenceNumber seqNum, Messages &&... messages) -> EnableSend< void, Messages... >
Sends one or more held messages as one packet to the primary feed.
Definition DataFeed.h:359
auto sendSecondary(SequenceNumber seqNum, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< void, Messages... >
Sends a packet holder's messages to the secondary feed.
Definition DataFeed.h:572
auto sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< void, Messages... >
Sends a temporary packet holder to the secondary feed with an explicit packet sending time.
Definition DataFeed.h:618
auto send(SequenceNumber seqNum, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< Threading::Event, Messages... >
Sends a packet holder's messages through the delivery policy.
Definition DataFeed.h:284
auto sendSecondary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Messages &&... messages) -> EnableSend< void, Messages... >
Sends one or more held messages to the secondary feed with an explicit packet sending time.
Definition DataFeed.h:515
void sendSecondary(SequenceNumber seqNum, Collection &&messages)
Sends a contiguous collection of encoded messages to the secondary feed.
Definition DataFeed.h:541
auto send(SequenceNumber seqNum, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< Threading::Event, Messages... >
Sends a temporary packet holder's messages through the delivery policy.
Definition DataFeed.h:321
auto sendPrimary(SequenceNumber seqNum, PacketHolder< Messages... > &packet) -> EnablePacketHolderSend< void, Messages... >
Sends a packet holder's messages to the primary feed.
Definition DataFeed.h:431
auto send(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Messages &&... messages) -> EnableSend< Threading::Event, Messages... >
Sends one or more held messages with an explicit packet sending time.
Definition DataFeed.h:217
virtual ~DataFeed()=default
Destroys the selected delivery policy and its resources.
std::array< ByteSpan, sizeof...(Messages)> MessageSpans
Fixed-size array of non-owning message byte views.
Definition DataFeed.h:142
auto sendSecondary(SequenceNumber seqNum, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< void, Messages... >
Sends a temporary packet holder's messages to the secondary feed.
Definition DataFeed.h:605
typename std::enable_if<(sizeof...(Messages)< SendMaxSpansCount), Result >::type EnablePacketHolderSend
Enables a result type for a packet holder within the delivery span limit.
Definition DataFeed.h:159
auto sendPrimary(SequenceNumber seqNum, PacketHolder< Messages... > &&packet) -> EnablePacketHolderSend< void, Messages... >
Sends a temporary packet holder's messages to the primary feed.
Definition DataFeed.h:464
auto sendPrimary(SequenceNumber seqNum, Messaging::Timestamp sendingTime, Messages &&... messages) -> EnableSend< void, Messages... >
Sends one or more held messages to the primary feed with an explicit packet sending time.
Definition DataFeed.h:374
DataFeed(Arguments &&... arguments)
Constructs the selected delivery policy with the supplied arguments.
Definition DataFeed.h:172
Owns a fixed set of CME message holders for sending in one packet.
MaterializedMessage(Message &&message) noexcept
Definition DataFeed.h:69
static Messaging::Timestamp now() noexcept
Returns current UTC time.
Definition Watch.h:66
SpanRange checkedSpans(Collection &spans, std::size_t maxSpansCount, std::size_t minSpansCount=0)
Definition Utils.h:98
ByteSpan asSpan(const PacketHeader &header) noexcept
Provides a read-only byte view of a packet header.
Definition Utils.h:114
std::span< const std::uint8_t > ByteSpan
Provides a non-owning read-only view over contiguous byte storage.
Definition ByteSpan.h:44
SharedFuture< void > Event
Completion signal for an asynchronous operation that does not produce a value.
Definition Future.h:208
Messaging::UInt32 SequenceNumber
Identifies a packet within an MDP packet sequence.
STL namespace.
Enum
Supported feed roles.