#pragma once #include #include #include #include "../common/adc_traits.h" namespace adc { template class AdcGenericNetMessage { // get a copy of message bytes template R bytes() const { R r; std::ranges::copy(_bytes, std::back_inserter(r)); return r; } virtual ByteStorageT bytes() const { return bytes(); } // get a view of message bytes template R bytesView() const { return R{_bytes.begin(), _bytes.end()}; } virtual ByteViewT bytesView() const { return bytesView(); } 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 class AdcTokenNetMessage : public AdcGenericNetMessage { using base_t = AdcGenericNetMessage; public: static constexpr std::string_view tokenDelimiter{TOKEN_DELIM}; template 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 requires std::ranges::view> R bytesView() const { R r; std::ranges::for_each(_tokens | std::views::take(_tokens.size()), [&r](const auto& el) { std::ranges::range_value_t 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 _tokens; }; } // namespace adc