Skip to content

Instantly share code, notes, and snippets.

@mavam
Created March 22, 2017 20:54
Show Gist options
  • Save mavam/c58e83d6d101662288affea126f2008e to your computer and use it in GitHub Desktop.
Save mavam/c58e83d6d101662288affea126f2008e to your computer and use it in GitHub Desktop.
A function that takes a discriminated union and writes it into a flexbuffer builder.
flexbuffers::Builder& build(flexbuffers::Builder& builder, const data& x) {
static auto to_uint = [](auto i) {
return static_cast<std::underlying_type_t<detail::DataType>>(i);
};
struct converter {
converter(flexbuffers::Builder& builder) : builder_{builder} {
}
void operator()(none) {
builder_.UInt(to_uint(detail::DataType::NoneType));
}
void operator()(boolean x) {
builder_.UInt(to_uint(detail::DataType::BooleanType));
builder_.UInt(x ? 1 : 0);
}
void operator()(integer x) {
builder_.UInt(to_uint(detail::DataType::IntegerType));
builder_.Int(x);
}
void operator()(count x) {
builder_.UInt(to_uint(detail::DataType::CountType));
builder_.UInt(x);
}
void operator()(real x) {
builder_.UInt(to_uint(detail::DataType::CountType));
builder_.Double(x);
}
void operator()(timestamp x) {
builder_.UInt(to_uint(detail::DataType::TimestampType));
builder_.UInt(x.time_since_epoch().count());
}
void operator()(timespan x) {
builder_.UInt(to_uint(detail::DataType::TimespanType));
builder_.UInt(x.count());
}
void operator()(const enumeration& x) {
builder_.UInt(to_uint(detail::DataType::EnumerationType));
builder_.UInt(x);
}
void operator()(const std::string& x) {
builder_.UInt(to_uint(detail::DataType::StringType));
builder_.String(x);
}
void operator()(const pattern& x) {
builder_.UInt(to_uint(detail::DataType::StringType));
builder_.String(x.string());
}
void operator()(const address& x) {
builder_.UInt(to_uint(detail::DataType::AddressType));
if (x.is_v4()) {
auto ptr = x.data().data() + 12;
builder_.UInt(*reinterpret_cast<const uint32_t*>(ptr));
} else {
builder_.Blob(x.data().data(), x.data().size());
}
}
void operator()(const subnet& x) {
builder_.UInt(to_uint(detail::DataType::SubnetType));
if (x.network().is_v4()) {
auto ptr = x.network().data().data() + 12;
builder_.UInt(*reinterpret_cast<const uint32_t*>(ptr));
} else {
builder_.Blob(x.network().data().data(), x.network().data().size());
}
}
void operator()(const port& x) {
builder_.UInt(to_uint(detail::DataType::PortType));
builder_.UInt(x.number());
builder_.UInt(static_cast<uint8_t>(x.type()));
}
void operator()(const vector& xs) {
builder_.Vector([&] {
for (auto& x : xs)
visit(*this, x);
});
}
void operator()(const set& xs) {
builder_.UInt(to_uint(detail::DataType::SetType));
builder_.Vector([&] {
for (auto& x : xs)
visit(*this, x);
});
}
void operator()(const table& xs) {
}
flexbuffers::Builder& builder_;
};
builder.Vector([&]{
visit(converter{builder}, x);
});
return builder;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment