summaryrefslogtreecommitdiff
path: root/include/CommonAPI/Struct.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/CommonAPI/Struct.hpp')
-rw-r--r--include/CommonAPI/Struct.hpp174
1 files changed, 174 insertions, 0 deletions
diff --git a/include/CommonAPI/Struct.hpp b/include/CommonAPI/Struct.hpp
new file mode 100644
index 0000000..c98b09e
--- /dev/null
+++ b/include/CommonAPI/Struct.hpp
@@ -0,0 +1,174 @@
+// Copyright (C) 2014-2015 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 <CommonAPI/CommonAPI.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef COMMONAPI_STRUCT_HPP_
+#define COMMONAPI_STRUCT_HPP_
+
+#include <iostream>
+#include <tuple>
+
+namespace CommonAPI {
+
+typedef uint32_t Serial;
+
+template<class _Derived>
+class InputStream;
+
+template<class _Derived>
+class OutputStream;
+
+template<class _Derived>
+class TypeOutputStream;
+
+template<int, class, class, class>
+struct StructReader;
+
+template<
+ int _Index, class _Input,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructReader<_Index, _Input, _V<_Values...>, _D<_Depls...>> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ StructReader<_Index-1, _Input, _V<_Values...>, _D<_Depls...>>{}(_input, _values, _depls);
+ _input.template readValue<>(std::get<_Index>(_values.values_),
+ (_depls ? std::get<_Index>(_depls->values_) : nullptr));
+ }
+};
+
+template<
+ int _Index, class _Input,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructReader<_Index, _Input, _V<_Values...>, _D> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D *_depls) {
+ StructReader<_Index-1, _Input, _V<_Values...>, _D>{}(_input, _values, _depls);
+ _input.template readValue<_D>(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _Input,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructReader<0, _Input, _V<_Values...>, _D<_Depls...>> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ _input.template readValue<>(std::get<0>(_values.values_),
+ (_depls ? std::get<0>(_depls->values_) : nullptr));
+ }
+};
+
+template<class _Input,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructReader<0, _Input, _V<_Values...>, _D> {
+ void operator()(InputStream<_Input> &_input,
+ _V<_Values...> &_values,
+ const _D *_depls) {
+ _input.template readValue<_D>(std::get<0>(_values.values_));
+ }
+};
+
+
+template< int, class, class, class >
+struct StructWriter;
+
+template<
+ int _Index, class _Output,
+ template<class ...> class _V, class... _Values,
+ template <class...> class _D, class... _Depls>
+struct StructWriter<_Index, _Output, _V<_Values...>, _D<_Depls...>> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ StructWriter<_Index-1, _Output, _V<_Values...>, _D<_Depls...>>{}(_output, _values, _depls);
+ _output.template writeValue<>(std::get<_Index>(_values.values_),
+ (_depls ? std::get<_Index>(_depls->values_) : nullptr));
+ }
+};
+
+template<
+ int _Index, class _Output,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructWriter<_Index, _Output, _V<_Values...>, _D> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D *_depls) {
+ StructWriter<_Index-1, _Output, _V<_Values...>, _D>{}(_output, _values, _depls);
+ _output.template writeValue<_D>(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _Output,
+ template<class...> class _V, class... _Values,
+ template<class...> class _D, class... _Depls>
+struct StructWriter<0, _Output, _V<_Values...>, _D<_Depls...>> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D<_Depls...> *_depls) {
+ _output.template writeValue<>(std::get<0>(_values.values_),
+ (_depls ? std::get<0>(_depls->values_) : nullptr));
+ }
+};
+
+template<class _Output,
+ template<class...> class _V, class... _Values,
+ class _D>
+struct StructWriter<0, _Output, _V<_Values...>, _D> {
+ void operator()(OutputStream<_Output> &_output,
+ const _V<_Values...> &_values,
+ const _D *_depls) {
+ _output.template writeValue<_D>(std::get<0>(_values.values_));
+ }
+};
+
+template<int, class, class>
+struct StructTypeWriter;
+
+template<int _Index, class _TypeOutput,
+ template<class...> class _V, class... _Values>
+struct StructTypeWriter<_Index, _TypeOutput, _V<_Values...>> {
+ void operator()(TypeOutputStream<_TypeOutput> &_output,
+ const _V<_Values...> &_values) {
+ StructTypeWriter<_Index-1, _TypeOutput, _V<_Values...>>{}(_output, _values);
+ _output.template writeType(std::get<_Index>(_values.values_));
+ }
+};
+
+template<class _TypeOutput,
+ template<class...> class _V, class... _Values>
+struct StructTypeWriter<0, _TypeOutput, _V<_Values...>> {
+ void operator()(TypeOutputStream<_TypeOutput> &_output,
+ const _V<_Values...> &_values) {
+ _output.template writeType(std::get<0>(_values.values_));
+ }
+};
+
+// 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<typename... _Types>
+struct Struct {
+ std::tuple<_Types...> 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 const Serial getSerial() const = 0;
+};
+
+} // namespace CommonAPI
+
+#endif // COMMONAPI_STRUCT_HPP_