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) {
76 if (!tts.check(tag)) {
83 }
else if constexpr (std::is_same<app::JustBytes, Message>::value) {
84 node.addJustBytesSubsFor(
85 [&tts, mod, res, &afterAddTag](uint16_t tag) {
86 if (tag % mod == res) {
87 if (!tts.check(tag)) {
93 }
else if (Message::typeTag % mod == res) {
94 auto tag = Message::typeTag;
95 if (!tts.check(tag)) {
101 next{}(node, tts, afterAddTag, mod, res);
105 template <MessageTupleC MessageTuple,
typename CcNode,
typename TypeTagSet>
107 void operator()(CcNode
const&,
TypeTagSet&, uint16_t mod, uint16_t res){}
110 template <MessageC Message, MessageC ...Messages,
typename CcNode,
typename TypeTagSet >
112 void operator()(CcNode
const& node,
TypeTagSet& tts, uint16_t mod, uint16_t res) {
113 if constexpr (Message::hasRange) {
114 node.addTypeTagRangePubsFor((Message*)
nullptr 115 , [&tts, mod, res](uint16_t offsetInRange) {
116 if (offsetInRange >= Message::typeTagRange) {
117 HMBDC_THROW(std::out_of_range, offsetInRange <<
" as offset is out of the range of " 118 << Message::typeTagStart <<
"_" << Message::typeTagRange);
120 if ((Message::typeTagStart + offsetInRange) % mod == res) {
121 tts.add(Message::typeTagStart + offsetInRange);
125 }
else if constexpr (std::is_same<app::JustBytes, Message>::value) {
126 node.addJustBytesPubsFor(
127 [&tts, mod, res](uint16_t tag) {
128 if (tag % mod == res) {
132 }
else if (Message::typeTag % mod == res) {
133 tts.add(Message::typeTag);
136 next{}(node, tts, mod, res);
142 using TagType = uint16_t;
144 capacity = 1u << (
sizeof(TagType) * 8),
147 template <MessageTupleC MessageTuple,
typename CcNode>
148 void addSubsFor(CcNode
const& node, uint16_t mod, uint16_t res
149 , std::function<
void(uint16_t)> afterAddTag = [](uint16_t){}) {
151 adder(node, *
this, afterAddTag, mod, res);
154 template <MessageTupleC MessageTuple>
155 void addAll(uint16_t mod = 1, uint16_t res = 0) {
159 uint8_t add(TagType tag) {
160 return ++subCounts_[tag];
163 bool set(TagType tag) {
164 if (subCounts_[tag])
return false;
165 return (subCounts_[tag] = 1);
168 bool unset(TagType tag) {
169 if (!subCounts_[tag])
return false;
179 uint8_t erase(TagType tag) {
180 return --subCounts_[tag];
183 uint8_t check(TagType tag)
const {
184 return subCounts_[tag];
187 template <
typename TagRecver>
188 void exportTo(TagRecver&& r)
const {
189 for (uint32_t i = 0; i < capacity; i++) {
190 auto c = (uint8_t)subCounts_[i];
198 std::atomic<TagType> subCounts_[capacity] = {0};
202 using TagType = uint16_t;
204 capacity = 1u << (
sizeof(TagType) * 8),
207 template <MessageTupleC MessageTuple,
typename CcNode>
208 void addSubsFor(CcNode
const& node, uint16_t mod, uint16_t res) {
210 adder(node, *
this, mod, res);
213 template <MessageTupleC MessageTuple,
typename CcNode>
214 void addPubsFor(CcNode
const& node, uint16_t mod, uint16_t res) {
216 adder(node, *
this, mod, res);
219 template <MessageTupleC MessageTuple>
220 void addAll(uint16_t mod = 1, uint16_t res = 0) {
224 uint8_t add(TagType tag) {
225 auto res = ++subCounts_[tag];
227 HMBDC_THROW(std::out_of_range,
"too many subscriptions - abort");
232 bool set(TagType tag) {
233 auto it = subCounts_.find(tag);
234 if (it == subCounts_.end())
return false;
238 bool unset(TagType tag) {
239 auto it = subCounts_.find(tag);
240 if (it == subCounts_.end())
return false;
254 uint8_t check(TagType tag)
const {
255 auto it = subCounts_.find(tag);
256 if (it == subCounts_.end())
return false;
260 template <
typename TagRecver>
261 void exportTo(TagRecver&& r)
const {
262 for (
auto const& t : subCounts_) {
264 r(t.first, t.second);
271 std::unordered_map<TagType, uint8_t> subCounts_;
Definition: TypedString.hpp:84