Created
March 22, 2017 20:54
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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