1 #include "hmbdc/Copyright.hpp" 3 #include "hmbdc/app/Message.hpp" 4 #include "hmbdc/Exception.hpp" 7 #include <unordered_map> 9 namespace hmbdc {
namespace tips {
11 namespace typetagset_detail {
12 template <
typename T, MessageTupleC MessageTuple>
15 void operator()(uint16_t mod, uint16_t res) {}
18 template <
typename T, MessageC Message, MessageC ...Messages>
19 struct adder<T,
std::tuple<Message, Messages...>> {
21 void operator()(uint16_t mod, uint16_t res) {
22 if constexpr (!Message::hasRange) {
23 if (Message::typeTag % mod == res) {
24 t.add(Message::typeTag);
27 for (uint16_t i = 0; i < Message::typeTagRange; ++i) {
28 auto tag = Message::typeTagStart + i;
29 if (tag % mod == res) {
34 adder<T, std::tuple<Messages...>>{t}(mod, res);
57 template <MessageTupleC MessageTuple,
typename CcNode,
typename TypeTagSet>
59 void operator()(CcNode
const&,
TypeTagSet&, std::function<
void(uint16_t)>
60 , uint16_t mod, uint16_t res){}
63 template <MessageC Message, MessageC ...Messages,
typename CcNode,
typename TypeTagSet >
65 void operator()(CcNode
const& node,
TypeTagSet& tts
66 , std::function<
void(uint16_t)> afterAddTag, uint16_t mod, uint16_t res) {
67 if constexpr (Message::hasRange) {
68 node.addTypeTagRangeSubsFor((Message*)
nullptr 69 , [&tts, mod, res, &afterAddTag](uint16_t offsetInRange) {
70 if (offsetInRange >= Message::typeTagRange) {
71 HMBDC_THROW(std::out_of_range, offsetInRange <<
" as offset is out of the range of " 72 << Message::typeTagStart <<
"_" << Message::typeTagRange);
74 auto tag = Message::typeTagStart + offsetInRange;
75 if (tag % mod == res) {
82 }
else if constexpr (std::is_same<app::JustBytes, Message>::value) {
83 node.addJustBytesSubsFor(
84 [&tts, mod, res, &afterAddTag](uint16_t tag) {
85 if (tag % mod == res) {
91 }
else if (Message::typeTag % mod == res) {
92 auto tag = Message::typeTag;
98 next{}(node, tts, afterAddTag, mod, res);
102 template <MessageTupleC MessageTuple,
typename CcNode,
typename TypeTagSet>
104 void operator()(CcNode
const&,
TypeTagSet&, uint16_t mod, uint16_t res){}
107 template <MessageC Message, MessageC ...Messages,
typename CcNode,
typename TypeTagSet >
109 void operator()(CcNode
const& node,
TypeTagSet& tts, uint16_t mod, uint16_t res) {
110 if constexpr (Message::hasRange) {
111 node.addTypeTagRangePubsFor((Message*)
nullptr 112 , [&tts, mod, res](uint16_t offsetInRange) {
113 if (offsetInRange >= Message::typeTagRange) {
114 HMBDC_THROW(std::out_of_range, offsetInRange <<
" as offset is out of the range of " 115 << Message::typeTagStart <<
"_" << Message::typeTagRange);
117 if ((Message::typeTagStart + offsetInRange) % mod == res) {
118 tts.set(Message::typeTagStart + offsetInRange);
122 }
else if constexpr (std::is_same<app::JustBytes, Message>::value) {
123 node.addJustBytesPubsFor(
124 [&tts, mod, res](uint16_t tag) {
125 if (tag % mod == res) {
129 }
else if (Message::typeTag % mod == res) {
130 tts.set(Message::typeTag);
133 next{}(node, tts, mod, res);
139 using TagType = uint16_t;
141 capacity = 1u << (
sizeof(TagType) * 8),
144 template <MessageTupleC MessageTuple,
typename CcNode>
145 void markSubsFor(CcNode
const& node, uint16_t mod, uint16_t res
146 , std::function<
void(uint16_t)> afterAddTag = [](uint16_t){}) {
148 marker(node, *
this, afterAddTag, mod, res);
151 template <MessageTupleC MessageTuple>
152 void addAll(uint16_t mod = 1, uint16_t res = 0) {
156 uint8_t add(TagType tag) {
157 return ++subCounts_[tag];
160 bool set(TagType tag) {
161 if (subCounts_[tag])
return false;
162 return (subCounts_[tag] = 1);
165 bool unset(TagType tag) {
166 if (!subCounts_[tag])
return false;
176 uint8_t sub(TagType tag) {
177 return --subCounts_[tag];
180 uint8_t check(TagType tag)
const {
181 return subCounts_[tag];
184 template <
typename TagRecver>
185 void exportTo(TagRecver&& r)
const {
186 for (uint32_t i = 0; i < capacity; i++) {
187 auto c = (uint8_t)subCounts_[i];
195 std::atomic<TagType> subCounts_[capacity] = {0};
199 using TagType = uint16_t;
201 capacity = 1u << (
sizeof(TagType) * 8),
204 template <MessageTupleC MessageTuple,
typename CcNode>
205 void markSubsFor(CcNode
const& node, uint16_t mod, uint16_t res) {
207 marker(node, *
this, mod, res);
210 template <MessageTupleC MessageTuple,
typename CcNode>
211 void markPubsFor(CcNode
const& node, uint16_t mod, uint16_t res) {
213 marker(node, *
this, mod, res);
216 template <MessageTupleC MessageTuple>
217 void addAll(uint16_t mod = 1, uint16_t res = 0) {
221 uint8_t add(TagType tag) {
222 auto res = ++subCounts_[tag];
224 HMBDC_THROW(std::out_of_range,
"too many subscriptions - abort");
229 bool set(TagType tag) {
230 auto it = subCounts_.find(tag);
231 if (it != subCounts_.end() && it->second)
return false;
232 return (subCounts_[tag] = 1);
235 bool unset(TagType tag) {
236 return subCounts_.erase(tag) == 1;
244 uint8_t sub(TagType tag) {
245 return --subCounts_[tag];
248 uint8_t check(TagType tag)
const {
249 auto it = subCounts_.find(tag);
250 if (it == subCounts_.end())
return false;
254 template <
typename TagRecver>
255 void exportTo(TagRecver&& r)
const {
256 for (
auto const& t : subCounts_) {
258 r(t.first, t.second);
265 std::unordered_map<TagType, uint8_t> subCounts_;
Definition: TypedString.hpp:84