// Copyright (c) 2017 Computer Vision Center (CVC) at the Universitat Autonoma // de Barcelona (UAB). // // This work is licensed under the terms of the MIT license. // For a copy, see . #pragma once #include "carla/Buffer.h" #include "carla/Memory.h" #include "carla/sensor/CompileTimeTypeMap.h" #include "carla/sensor/RawData.h" namespace carla { namespace sensor { class SensorData; // =========================================================================== // -- CompositeSerializer ---------------------------------------------------- // =========================================================================== /// Compile-time map for mapping sensor objects to serializers. The /// appropriate serializer is called for each sensor to serialize and /// deserialize its data. /// /// Do not use directly, use the SensorRegistry instantiation. template class CompositeSerializer : public CompileTimeTypeMap { using Super = CompileTimeTypeMap; public: using interpreted_type = SharedPtr; /// Serialize the arguments provided into a Buffer by calling to the /// serializer registered for the given @a Sensor type. template static Buffer Serialize(Sensor &sensor, Args &&... args); /// Deserializes a Buffer by calling the "Deserialize" function of the /// serializer that generated the Buffer. static interpreted_type Deserialize(Buffer &&data); private: template static interpreted_type Deserialize_impl(Data &&data) { using Serializer = typename Super::template get_by_index::type; return Serializer::Deserialize(std::forward(data)); } template static interpreted_type Deserialize_impl(size_t i, Data &&data, std::index_sequence) { // This function is equivalent to creating a switch statement with a case // for each element in the map, the compiler should be able to optimize it // into a jump table. See https://stackoverflow.com/a/46282159/5308925. interpreted_type result; std::initializer_list ({ (i == Is ? (result = Deserialize_impl(std::forward(data))), 0 : 0)... }); return result; } template static interpreted_type Deserialize(size_t index, Data &&data) { return Deserialize_impl( index, std::forward(data), std::make_index_sequence()); } }; // =========================================================================== // -- CompositeSerializer implementation ------------------------------------- // =========================================================================== template template inline Buffer CompositeSerializer::Serialize(Sensor &sensor, Args &&... args) { using TheSensor = typename std::remove_const::type; using Serializer = typename Super::template get::type; return Serializer::Serialize(sensor, std::forward(args)...); } template inline typename CompositeSerializer::interpreted_type CompositeSerializer::Deserialize(Buffer &&data) { RawData message{std::move(data)}; size_t index = message.GetSensorTypeId(); return Deserialize(index, std::move(message)); } } // namespace sensor } // namespace carla