#pragma once #include static std::function(TiltedPhoques::Buffer::Reader& aReader)> s_clientMessageExtractor[kClientOpcodeMax]; namespace details { static struct ClientMessageFactoryInit { ClientMessageFactoryInit() { auto extractor = [](auto& x) { using T = typename std::remove_reference_t::Type; s_clientMessageExtractor[T::Opcode] = [](TiltedPhoques::Buffer::Reader& aReader) { auto ptr = TiltedPhoques::MakeUnique(); ptr->DeserializeRaw(aReader); return TiltedPhoques::CastUnique(std::move(ptr)); }; return false; }; ClientMessageFactory::Visit(extractor); } } s_ClientMessageFactoryInit; } // namespace details UniquePtr ClientMessageFactory::Extract(TiltedPhoques::Buffer::Reader& aReader) const noexcept { uint64_t data; aReader.ReadBits(data, sizeof(ClientOpcode) * 8); if (data >= kClientOpcodeMax) [[unlikely]] return {nullptr}; const auto opcode = static_cast(data); return s_clientMessageExtractor[opcode](aReader); }