... add reserved elements conception

This commit is contained in:
Timur A. Fatkhullin 2024-06-05 12:45:17 +03:00
parent cf543feeb5
commit efa48ee132
2 changed files with 103 additions and 86 deletions

View File

@ -127,7 +127,8 @@ public:
} }
bool emp = true; bool emp = true;
for (const auto& el : _bytes) { for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
const auto& el = _bytes[i];
if (std::ranges::distance(el.begin(), el.end())) { if (std::ranges::distance(el.begin(), el.end())) {
emp = false; emp = false;
break; break;
@ -143,7 +144,7 @@ public:
{ {
R r; R r;
for (size_t i = 0; i < _bytes.size(); ++i) { for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
std::ranges::for_each(storageViewByIndex(i), std::ranges::for_each(storageViewByIndex(i),
[&r](const auto& el) { std::ranges::copy(el, std::back_inserter(r)); }); [&r](const auto& el) { std::ranges::copy(el, std::back_inserter(r)); });
} }
@ -152,7 +153,7 @@ public:
} }
virtual ByteStorageT bytes() const ByteStorageT bytes() const
{ {
// //
return bytes<ByteStorageT>(); return bytes<ByteStorageT>();
@ -165,7 +166,7 @@ public:
R r; R r;
for (size_t i = 0; i < _bytes.size(); ++i) { for (size_t i = _reservedNum; i < _bytes.size(); ++i) {
std::ranges::for_each(storageViewByIndex(i), std::ranges::for_each(storageViewByIndex(i),
[&r](const auto& el) { r.emplace_back(el.begin(), el.end()); }); [&r](const auto& el) { r.emplace_back(el.begin(), el.end()); });
} }
@ -181,9 +182,14 @@ public:
protected: protected:
std::vector<ByteStorageT> _bytes; std::vector<ByteStorageT> _bytes;
size_t _reservedNum;
AdcNetMessageSeqInterface() = default; AdcNetMessageSeqInterface(size_t reserved = 0) : _reservedNum(reserved), _bytes()
{
// reserve the "_reservedNum" first elements
_bytes.resize(_reservedNum);
}
// return a sequence of storage element view and possible additional // return a sequence of storage element view and possible additional
// byte views (e.g. elements delimiter) // byte views (e.g. elements delimiter)
@ -272,7 +278,7 @@ public:
AdcTokenNetMessage() = default; AdcTokenNetMessage() = default;
template <typename T, typename... Ts> template <typename T, typename... Ts>
AdcTokenNetMessage(const T& v, const Ts&... vs) : AdcTokenNetMessage() AdcTokenNetMessage(const T& v, const Ts&... vs) : AdcTokenNetMessage() // _reservedNum = 0
{ {
setTokens(v, vs...); setTokens(v, vs...);
} }
@ -289,7 +295,8 @@ public:
return r; return r;
} }
std::ranges::copy(this->_bytes | std::views::drop(start) | std::views::take(N), std::back_inserter(r)); std::ranges::copy(this->_bytes | std::views::drop(start + this->_reservedNum) | std::views::take(N),
std::back_inserter(r));
return r; return r;
} }
@ -306,11 +313,12 @@ public:
{ {
R r; R r;
if (empty() || (start >= this->_bytes.size()) || !N) { if (empty() || (start >= _tokenNumber) || !N) {
return r; return r;
} }
utils::AdcJoinRange(this->_bytes | std::views::drop(start) | std::views::take(N), tokenDelimiter, r); utils::AdcJoinRange(this->_bytes | std::views::drop(start + this->_reservedNum) | std::views::take(N),
tokenDelimiter, r);
return r; return r;
} }
@ -345,13 +353,16 @@ public:
if constexpr (sizeof...(Ts)) { if constexpr (sizeof...(Ts)) {
appendTokens(vs...); appendTokens(vs...);
} }
_tokenNumber = this->_bytes.size() - this->_reservedNum;
} }
template <typename T, typename... Ts> template <typename T, typename... Ts>
void setTokens(const T& v, const Ts&... vs) void setTokens(const T& v, const Ts&... vs)
{ {
this->_bytes.clear(); this->_bytes.resize(this->_reservedNum);
_tokenNumber = 0;
appendTokens(v, vs...); appendTokens(v, vs...);
} }
@ -366,6 +377,8 @@ public:
do { do {
it = std::search(start_it, end, tokenDelimiter.begin(), tokenDelimiter.end()); it = std::search(start_it, end, tokenDelimiter.begin(), tokenDelimiter.end());
std::copy(start_it, it, std::back_inserter(this->_bytes.emplace_back())); std::copy(start_it, it, std::back_inserter(this->_bytes.emplace_back()));
++_tokenNumber;
start_it = it; start_it = it;
std::advance(start_it, tokenDelimiter.size()); // to support not only random-access iterators std::advance(start_it, tokenDelimiter.size()); // to support not only random-access iterators
} while (it != end); } while (it != end);
@ -376,19 +389,22 @@ public:
void setFromBytes(IT begin, IT end) void setFromBytes(IT begin, IT end)
requires std::same_as<std::iter_value_t<IT>, char> requires std::same_as<std::iter_value_t<IT>, char>
{ {
this->_bytes.clear(); this->_bytes.resize(this->_reservedNum);
_tokenNumber = 0;
appendFromBytes(begin, end); appendFromBytes(begin, end);
} }
protected: protected:
size_t _tokenNumber;
virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override
{ {
const ByteStorageT& el = this->_bytes[idx]; const ByteStorageT& el = this->_bytes[idx];
std::vector<ByteViewT> vw{{el.begin(), el.end()}}; std::vector<ByteViewT> vw{{el.begin(), el.end()}};
auto last_idx = this->_bytes.size() - 1; auto last_idx = this->_bytes.size() - 1;
if (idx < last_idx) { // add delimiter if ((idx < last_idx) && (_tokenNumber > 1)) { // add delimiter
vw.emplace_back(tokenDelimiter.begin(), tokenDelimiter.end()); vw.emplace_back(tokenDelimiter.begin(), tokenDelimiter.end());
} }
@ -421,29 +437,85 @@ public:
using base_t::tokens; using base_t::tokens;
AdcKeyTokenNetMessage() = default; AdcKeyTokenNetMessage()
{
this->_reservedNum = 1; // reserve the first element for keyword
this->_bytes.resize(this->_reservedNum);
};
template <typename KT, typename T, typename... Ts> template <typename KT, typename T, typename... Ts>
AdcKeyTokenNetMessage(const KT& key, const T& tok, const Ts&... toks) AdcKeyTokenNetMessage(const KT& key, const T& tok, const Ts&... toks) : AdcKeyTokenNetMessage()
{ {
utils::convertToBytes(this->_bytes.emplace_back(), key); utils::convertToBytes(this->_bytes[0], key);
setTokens(tok, toks...); setTokens(tok, toks...);
} }
virtual ~AdcKeyTokenNetMessage() = default; virtual ~AdcKeyTokenNetMessage() = default;
// get a copy of message bytes
template <traits::adc_output_char_range R>
R bytes() const
{
R r;
std::ranges::copy(this->_bytes[0], std::back_inserter(r)); // keyword
if (this->_tokenNumber) {
std::ranges::copy(keytokenDelimiter, std::back_inserter(r)); // keyword-to-token delimiter
}
std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
std::ranges::copy(el, std::back_inserter(r)); // token
});
return r;
}
ByteStorageT bytes() const
{
//
return bytes<ByteStorageT>();
}
// get a view of message bytes
template <traits::adc_range_of_view_char_range R>
R bytesView() const
{
R r;
const auto& key = this->_bytes[0];
std::back_inserter(r) = {key.begin(), key.end()}; // keyword
if (this->_tokenNumber) {
std::back_inserter(r) = {keytokenDelimiter.begin(), keytokenDelimiter.end()}; // keyword-to-token delimiter
}
std::ranges::for_each(base_t::template bytesView(), [&r](const auto& el) {
std::back_inserter(r) = {el.begin(), el.end()}; // token
});
return r;
}
std::vector<ByteViewT> bytesView() const
{
//
return bytesView<std::vector<ByteViewT>>();
}
template <traits::adc_output_char_range R> template <traits::adc_output_char_range R>
R keyBytes() const R keyBytes() const
{ {
R r; R r;
if (empty()) { const auto& key = this->_bytes[0];
if (!std::distance(key.begin(), key.end())) {
return r; return r;
} }
std::ranges::copy(this->_bytes[0], r); std::ranges::copy(key, std::back_inserter(r));
return r; return r;
} }
@ -451,18 +523,16 @@ public:
ByteStorageT keyBytes() const ByteStorageT keyBytes() const
{ {
if (empty()) { //
return ByteStorageT(); return keyBytes<ByteStorageT>();
}
return this->_bytes[0];
} }
template <traits::adc_char_view R> template <traits::adc_char_view R>
R keyView() const R keyView() const
{ {
if (empty()) { const auto& key = this->_bytes[0];
if (!std::distance(key.begin(), key.end())) {
return R(); return R();
} }
@ -471,60 +541,20 @@ public:
ByteViewT keyView() const ByteViewT keyView() const
{
if (empty()) {
return ByteViewT();
}
return ByteViewT{this->_bytes[0].begin(), this->_bytes[0].end()};
}
template <std::ranges::output_range<ByteStorageT> R>
R tokens(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
// "+1" since the first element is keyword
return base_t::template tokens<R>(start + 1, N);
}
std::vector<ByteStorageT> tokens(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{ {
// //
return tokens<std::vector<ByteStorageT>>(start, N); return keyView<ByteViewT>();
} }
template <traits::adc_output_char_range R>
R tokensBytes(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
// "+1" since the first element is keyword
return base_t::template tokensBytes<ByteStorageT>(start + 1, N);
}
ByteStorageT tokensBytes(size_t start = 0, size_t N = std::numeric_limits<size_t>::max()) const
{
return tokensBytes<ByteStorageT>(start, N);
}
template <typename KT, typename T, typename... Ts> template <typename KT, typename T, typename... Ts>
void setKeyTokens(const KT& key, const T& tok, const Ts&... toks) void setKeyTokens(const KT& key, const T& tok, const Ts&... toks)
{ {
this->_bytes.clear(); setTokens(tok, toks...);
utils::convertToBytes(this->_bytes[0], key);
utils::convertToBytes(this->_bytes.emplace_back(), key);
appendTokens(tok, toks...);
} }
template <typename T, typename... Ts>
void setTokens(const T& v, const Ts&... vs)
{
this->_bytes.resize(1); // the first element is keyword
appendTokens(v, vs...);
}
template <std::input_iterator IT> template <std::input_iterator IT>
void setFromBytes(IT begin, IT end) void setFromBytes(IT begin, IT end)
@ -541,23 +571,6 @@ public:
appendFromBytes(it, end); // tokens appendFromBytes(it, end); // tokens
} }
} }
protected:
virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override
{
if (idx == 0) { // the first element is keyword
const ByteStorageT& el = this->_bytes[idx];
std::vector<ByteViewT> vw{{el.begin(), el.end()}};
if (this->_bytes.size() > 1) { // there are tokens, so add keyword-to-tokens delimiter
vw.emplace_back(keytokenDelimiter.begin(), keytokenDelimiter.end());
}
return vw;
} else {
return base_t::storageViewByIndex(idx);
}
}
}; };
} // namespace adc } // namespace adc

View File

@ -36,9 +36,11 @@ TEST_CASE("[ADC NET MESSAGE]")
} }
auto t2 = msg.bytesView(); auto t2 = msg.bytesView();
std::cout << "BYTES VIEW: ";
for (auto& el : t2) { for (auto& el : t2) {
std::cout << "BYTES VIEW: [" << el << "]\n"; std::cout << "[" << el << "]";
} }
std::cout << "\n";
std::cout << "\n\n---------\n\n"; std::cout << "\n\n---------\n\n";
@ -47,7 +49,7 @@ TEST_CASE("[ADC NET MESSAGE]")
msg.setTokens("FILTER", "A1", "B3"); msg.setTokens("FILTER", "A1", "B3");
std::cout << "BYTES: " << msg.bytes() << "\n"; std::cout << "BYTES: " << msg.bytes() << "\n";
std::cout << "TOK BYTES: " << msg.tokensBytes(1, 1) << "\n"; std::cout << "TOK BYTES: [" << msg.tokensBytes(1, 1) << "]\n";
std::cout << "\n\n---------\n\n"; std::cout << "\n\n---------\n\n";
@ -59,9 +61,11 @@ TEST_CASE("[ADC NET MESSAGE]")
tmsg.setFromBytes(bb.begin(), bb.end()); tmsg.setFromBytes(bb.begin(), bb.end());
auto t1 = tmsg.bytesView(); auto t1 = tmsg.bytesView();
std::cout << "TOKENS VIEW: ";
for (auto& el : t1) { for (auto& el : t1) {
std::cout << "TOKEN VIEW: [" << el << "]\n"; std::cout << "[" << el << "]";
} }
std::cout << "\n";
} }
/* /*