src/scale/detail/variant.hpp¶
Namespaces¶
| Name |
|---|
| sgns |
| sgns::scale |
| sgns::scale::detail |
| sgns::scale::detail::variant_impl |
Classes¶
| Name | |
|---|---|
| class | sgns::scale::detail::variant_impl::VariantEncoder |
| class | sgns::scale::detail::variant_impl::VariantDecoder |
Functions¶
| Name | |
|---|---|
| template <class F ,class H > void |
apply_once(F & f, uint8_t i) |
| template <uint8_t i,class F ,class H ,class... T> void |
for_each_apply_impl(F & f) |
| template <uint8_t i,class F > void |
for_each_apply_impl(F & f) |
| template <class F ,class... T> void |
for_each_apply(F & f) |
| template <class Stream ,class... T> Stream & |
encodeVariant(const boost::variant< T... > & v, Stream & s) encodes boost::variant value |
| template <class Stream ,class... T> Stream & |
decodeVariant(Stream & stream, boost::variant< T... > & result) decodes variant value |
Functions Documentation¶
function apply_once¶
function for_each_apply_impl¶
function for_each_apply_impl¶
function for_each_apply¶
function encodeVariant¶
template <class Stream ,
class... T>
Stream & encodeVariant(
const boost::variant< T... > & v,
Stream & s
)
encodes boost::variant value
Parameters:
- v variant value
- s encoder stream
Template Parameters:
- Stream output stream type
- T... sequence of types
function decodeVariant¶
template <class Stream ,
class... T>
Stream & decodeVariant(
Stream & stream,
boost::variant< T... > & result
)
decodes variant value
Parameters:
- stream source stream
- result destination variant
Template Parameters:
- Stream input stream type
- T... sequence of types
Return: decoded value or error
Source code¶
#ifndef SUPERGENIUS_SCALE_DETAIL_VARIANT_HPP
#define SUPERGENIUS_SCALE_DETAIL_VARIANT_HPP
#include <boost/variant.hpp>
#include "base/outcome_throw.hpp"
#include "base/visitor.hpp"
#include "scale/scale_error.hpp"
namespace sgns::scale::detail {
namespace variant_impl {
template <class F, class H>
void apply_once(F &f, uint8_t i) {
f.template apply<H>(i);
}
template <uint8_t i, class F, class H, class... T>
void for_each_apply_impl(F &f) {
apply_once<F, H>(f, i);
for_each_apply_impl<i + 1, F, T...>(f);
}
template <uint8_t i, class F>
void for_each_apply_impl(F &f) {
// do nothing, end of recursion
}
template <class Stream, class... T>
class VariantEncoder {
public:
VariantEncoder(const boost::variant<T...> &v, Stream &s) : v_{v}, s_{s} {}
template <class H>
void apply(uint8_t index) {
// if type matches alternative in variant then encode
sgns::visit_in_place(v_,
[this, index](const H &h) {
s_ << index
<< h; // first byte means type index
},
[](const auto & /*unused*/) {});
}
private:
const boost::variant<T...> &v_;
Stream &s_;
};
template <class Stream, class... T>
class VariantDecoder {
public:
VariantDecoder(uint8_t type_index, boost::variant<T...> &r, Stream &s)
: type_index_{type_index}, r_{r}, s_{s} {};
template <class H>
void apply(uint8_t index) {
if (index == type_index_) {
H h{};
s_ >> h; // decode custom type
r_ = std::move(h);
}
}
private:
uint8_t type_index_;
boost::variant<T...> &r_;
Stream &s_;
};
template <class F, class... T>
void for_each_apply(F &f) {
variant_impl::for_each_apply_impl<0, F, T...>(f);
}
} // namespace variant_impl
template <class Stream, class... T>
Stream &encodeVariant(const boost::variant<T...> &v, Stream &s) {
auto &&encoder = variant_impl::VariantEncoder(v, s);
variant_impl::for_each_apply<decltype(encoder), T...>(encoder);
return s;
}
template <class Stream, class... T>
Stream &decodeVariant(Stream &stream, boost::variant<T...> &result) {
// first byte means type index
uint8_t type_index = 0u;
stream >> type_index; // decode type index
static constexpr uint8_t types_count = sizeof...(T);
// ensure that index is in [0, types_count)
if (type_index >= types_count) {
base::raise(DecodeError::WRONG_TYPE_INDEX);
}
auto &&decoder = variant_impl::VariantDecoder(type_index, result, stream);
variant_impl::for_each_apply<decltype(decoder), T...>(decoder);
return stream;
}
} // namespace sgns::scale::detail
#endif // SUPERGENIUS_SCALE_DETAIL_VARIANT_HPP
Updated on 2026-03-04 at 13:10:45 -0800