This commit is contained in:
Timur A. Fatkhullin 2024-06-01 21:40:13 +03:00
parent 4edd3ee21f
commit 65cd65b2d8
2 changed files with 113 additions and 0 deletions

View File

@ -42,6 +42,10 @@ concept adc_input_char_range =
std::ranges::input_range<R> && std::is_same_v<std::remove_cv_t<std::ranges::range_value_t<R>>, CharT>;
template <typename R>
concept adc_char_view = std::ranges::view<R> && std::same_as<std::ranges::range_value_t<R>, char>;
// deduce returned type of callable
// template <typename T>
// using adc_retval_t = std::invoke_result_t<std::remove_cvref_t<T>>;

109
net/adc_netmsg.h Normal file
View File

@ -0,0 +1,109 @@
#pragma once
#include <algorithm>
#include <string>
#include <vector>
#include "../common/adc_traits.h"
namespace adc
{
template <traits::adc_output_char_range ByteStorageT = std::string, traits::adc_char_view ByteViewT = std::string_view>
class AdcGenericNetMessage
{
// get a copy of message bytes
template <traits::adc_output_char_range R>
R bytes() const
{
R r;
std::ranges::copy(_bytes, std::back_inserter(r));
return r;
}
virtual ByteStorageT bytes() const { return bytes<ByteStorageT>(); }
// get a view of message bytes
template <traits::adc_char_view R>
R bytesView() const
{
return R{_bytes.begin(), _bytes.end()};
}
virtual ByteViewT bytesView() const { return bytesView<ByteViewT>(); }
protected:
ByteStorageT _bytes;
};
namespace constants
{
static constexpr char ADC_DEFAULT_TOKEN_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_KEY_PARAM_DELIMITER[] = " ";
static constexpr char ADC_DEFAULT_PARAM_PARAM_DELIMITER[] = " ";
} // namespace constants
template <const char* TOKEN_DELIM = constants::ADC_DEFAULT_TOKEN_DELIMITER,
traits::adc_output_char_range ByteStorageT = std::string,
traits::adc_char_view ByteViewT = std::string_view>
class AdcTokenNetMessage : public AdcGenericNetMessage<ByteStorageT, ByteViewT>
{
using base_t = AdcGenericNetMessage<ByteStorageT, ByteViewT>;
public:
static constexpr std::string_view tokenDelimiter{TOKEN_DELIM};
template <traits::adc_output_char_range R>
R bytes() const
{
R r;
if (_tokens.empty()) {
return r;
}
std::ranges::for_each(_tokens | std::views::take(_tokens.size()), [&r](const auto& el) {
std::ranges::copy(el, std::back_inserter(r));
std::ranges::copy(tokenDelimiter, std::back_inserter(r));
});
std::ranges::copy(_tokens.back(), std::back_inserter(r));
return r;
}
template <std::ranges::range R>
requires std::ranges::view<std::ranges::range_value_t<R>>
R bytesView() const
{
R r;
std::ranges::for_each(_tokens | std::views::take(_tokens.size()), [&r](const auto& el) {
std::ranges::range_value_t<R> v{el.begin(), el.end()};
std::back_inserter(r) = {el.begin(), el.end()};
std::back_inserter(r) = {tokenDelimiter.begin(), tokenDelimiter.end()};
});
std::back_inserter(r) = {_tokens.back().begin(), _tokens.back().end()};
return r;
}
protected:
std::vector<ByteStorageT> _tokens;
};
} // namespace adc