... 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;
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())) {
emp = false;
break;
@ -143,7 +144,7 @@ public:
{
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),
[&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>();
@ -165,7 +166,7 @@ public:
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),
[&r](const auto& el) { r.emplace_back(el.begin(), el.end()); });
}
@ -181,9 +182,14 @@ public:
protected:
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
// byte views (e.g. elements delimiter)
@ -272,7 +278,7 @@ public:
AdcTokenNetMessage() = default;
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...);
}
@ -289,7 +295,8 @@ public:
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;
}
@ -306,11 +313,12 @@ public:
{
R r;
if (empty() || (start >= this->_bytes.size()) || !N) {
if (empty() || (start >= _tokenNumber) || !N) {
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;
}
@ -345,13 +353,16 @@ public:
if constexpr (sizeof...(Ts)) {
appendTokens(vs...);
}
_tokenNumber = this->_bytes.size() - this->_reservedNum;
}
template <typename T, typename... Ts>
void setTokens(const T& v, const Ts&... vs)
{
this->_bytes.clear();
this->_bytes.resize(this->_reservedNum);
_tokenNumber = 0;
appendTokens(v, vs...);
}
@ -366,6 +377,8 @@ public:
do {
it = std::search(start_it, end, tokenDelimiter.begin(), tokenDelimiter.end());
std::copy(start_it, it, std::back_inserter(this->_bytes.emplace_back()));
++_tokenNumber;
start_it = it;
std::advance(start_it, tokenDelimiter.size()); // to support not only random-access iterators
} while (it != end);
@ -376,19 +389,22 @@ public:
void setFromBytes(IT begin, IT end)
requires std::same_as<std::iter_value_t<IT>, char>
{
this->_bytes.clear();
this->_bytes.resize(this->_reservedNum);
_tokenNumber = 0;
appendFromBytes(begin, end);
}
protected:
size_t _tokenNumber;
virtual std::vector<ByteViewT> storageViewByIndex(size_t idx) const override
{
const ByteStorageT& el = this->_bytes[idx];
std::vector<ByteViewT> vw{{el.begin(), el.end()}};
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());
}
@ -421,29 +437,85 @@ public:
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>
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...);
}
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>
R keyBytes() const
{
R r;
if (empty()) {
const auto& key = this->_bytes[0];
if (!std::distance(key.begin(), key.end())) {
return r;
}
std::ranges::copy(this->_bytes[0], r);
std::ranges::copy(key, std::back_inserter(r));
return r;
}
@ -451,18 +523,16 @@ public:
ByteStorageT keyBytes() const
{
if (empty()) {
return ByteStorageT();
}
return this->_bytes[0];
//
return keyBytes<ByteStorageT>();
}
template <traits::adc_char_view R>
R keyView() const
{
if (empty()) {
const auto& key = this->_bytes[0];
if (!std::distance(key.begin(), key.end())) {
return R();
}
@ -471,60 +541,20 @@ public:
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>
void setKeyTokens(const KT& key, const T& tok, const Ts&... toks)
{
this->_bytes.clear();
utils::convertToBytes(this->_bytes.emplace_back(), key);
appendTokens(tok, toks...);
setTokens(tok, toks...);
utils::convertToBytes(this->_bytes[0], key);
}
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>
void setFromBytes(IT begin, IT end)
@ -541,23 +571,6 @@ public:
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

View File

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