// Copyright (C) 2014-2020 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #if !defined (COMMONAPI_INTERNAL_COMPILATION) #error "Only can be included directly, this file may disappear or change contents." #endif #ifndef COMMONAPI_STRUCT_HPP_ #define COMMONAPI_STRUCT_HPP_ #include #include namespace CommonAPI { typedef uint32_t Serial; template class InputStream; template class OutputStream; template class TypeOutputStream; template struct StructReader; template< int Index_, class Input_, template class V_, class... Values_, template class D_, class... Depls_> struct StructReader, D_> { void operator()(InputStream &_input, V_ &_values, const D_ *_depls) { StructReader, D_>{}(_input, _values, _depls); _input.template readValue<>(std::get(_values.values_), (_depls ? std::get(_depls->values_) : nullptr)); } }; template< int Index_, class Input_, template class V_, class... Values_, class D_> struct StructReader, D_> { void operator()(InputStream &_input, V_ &_values, const D_ *_depls) { StructReader, D_>{}(_input, _values, _depls); _input.template readValue(std::get(_values.values_)); } }; template class V_, class... Values_, template class D_, class... Depls_> struct StructReader<0, Input_, V_, D_> { void operator()(InputStream &_input, V_ &_values, const D_ *_depls) { _input.template readValue<>(std::get<0>(_values.values_), (_depls ? std::get<0>(_depls->values_) : nullptr)); } }; template class V_, class... Values_, class D_> struct StructReader<0, Input_, V_, D_> { void operator()(InputStream &_input, V_ &_values, const D_ *_depls) { (void)_depls; _input.template readValue(std::get<0>(_values.values_)); } }; template< int, class, class, class > struct StructWriter; template< int Index_, class Output_, template class V_, class... Values_, template class D_, class... Depls_> struct StructWriter, D_> { void operator()(OutputStream &_output, const V_ &_values, const D_ *_depls) { StructWriter, D_>{}(_output, _values, _depls); _output.template writeValue<>(std::get(_values.values_), (_depls ? std::get(_depls->values_) : nullptr)); } }; template< int Index_, class Output_, template class V_, class... Values_, class D_> struct StructWriter, D_> { void operator()(OutputStream &_output, const V_ &_values, const D_ *_depls) { StructWriter, D_>{}(_output, _values, _depls); _output.template writeValue(std::get(_values.values_)); } }; template class V_, class... Values_, template class D_, class... Depls_> struct StructWriter<0, Output_, V_, D_> { void operator()(OutputStream &_output, const V_ &_values, const D_ *_depls) { _output.template writeValue<>(std::get<0>(_values.values_), (_depls ? std::get<0>(_depls->values_) : nullptr)); } }; template class V_, class... Values_, class D_> struct StructWriter<0, Output_, V_, D_> { void operator()(OutputStream &_output, const V_ &_values, const D_ *_depls) { (void)_depls; _output.template writeValue(std::get<0>(_values.values_)); } }; template struct StructTypeWriter; template class V_, class... Values_> struct StructTypeWriter> { void operator()(TypeOutputStream &_output, const V_ &_values, const EmptyDeployment *_depl = nullptr) { StructTypeWriter>{}(_output, _values, _depl); #ifdef _WIN32 _output.writeType(std::get(_values.values_), _depl); #else _output.template writeType(std::get(_values.values_), _depl); #endif } }; template class V_, class... Values_> struct StructTypeWriter> { void operator()(TypeOutputStream &_output, const V_ &_values, const EmptyDeployment *_depl = nullptr) { #ifdef _WIN32 _output.writeType(std::get<0>(_values.values_), _depl); #else _output.template writeType(std::get<0>(_values.values_), _depl); #endif } }; template class V_, class... Values_> struct StructTypeWriter> { void operator()(TypeOutputStream &_output, const V_ &_values, const Deployment_ *_depl = nullptr) { StructTypeWriter>{}(_output, _values, _depl); #ifdef _WIN32 _output.writeType(std::get(_values.values_), (_depl ? std::get(_depl->values_) : nullptr)); #else _output.template writeType(std::get(_values.values_), (_depl ? std::get(_depl->values_) : nullptr)); #endif } }; template class V_, class... Values_> struct StructTypeWriter> { void operator()(TypeOutputStream &_output, const V_ &_values, const Deployment_ *_depl = nullptr) { #ifdef _WIN32 _output.writeType(std::get<0>(_values.values_), (_depl ? std::get<0>(_depl->values_) : nullptr)); #else _output.template writeType(std::get<0>(_values.values_), (_depl ? std::get<0>(_depl->values_) : nullptr)); #endif } }; // Structures are mapped to a (generated) struct which inherits from CommonAPI::Struct. // CommonAPI::Struct holds the structured data in a tuple. The generated class provides // getter- and setter-methods for the structure members. template struct Struct { std::tuple values_; }; // Polymorphic structs are mapped to an interface that is derived from the base class // PolymorphicStruct and contain their parameter in a Struct. struct PolymorphicStruct { virtual ~PolymorphicStruct() {}; virtual Serial getSerial() const = 0; }; } // namespace CommonAPI #endif // COMMONAPI_STRUCT_HPP_