source: finroc_plugins_composite_ports/internal/type_traits.h @ 28:0d9e9fd957de

Last change on this file since 28:0d9e9fd957de was 23:3c9cac2a0cc1, checked in by Max Reichardt <mreichardt@…>, 23 months ago

Adds 'interface modifiers' for customization of port composite interface creation (as there are diverse use cases). Refactors and tidies partial interface creation with this new feature.

File size: 11.4 KB
Line 
1//
2// You received this file as part of Finroc
3// A framework for intelligent robot control
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    plugins/composite_ports/internal/type_traits.h
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2020-02-11
27 *
28 * Type traits with respect to port types in particular
29 *
30 */
31//----------------------------------------------------------------------
32#ifndef __plugins__structure__internal__type_traits_h__
33#define __plugins__structure__internal__type_traits_h__
34
35//----------------------------------------------------------------------
36// External includes (system with <>, local with "")
37//----------------------------------------------------------------------
38#include "plugins/data_ports/tGenericPort.h"
39#include "plugins/data_ports/tInputPort.h"
40#include "plugins/data_ports/tOutputPort.h"
41#include "plugins/data_ports/tProxyPort.h"
42#include "plugins/parameters/tParameter.h"
43
44#ifdef _LIB_FINROC_PLUGINS_RPC_PORTS_PRESENT_
45#include "plugins/rpc_ports/tServerPort.h"
46#include "plugins/rpc_ports/tClientPort.h"
47#include "plugins/rpc_ports/tProxyPort.h"
48#endif
49
50//----------------------------------------------------------------------
51// Internal includes with ""
52//----------------------------------------------------------------------
53
54//----------------------------------------------------------------------
55// Namespace declaration
56//----------------------------------------------------------------------
57namespace finroc
58{
59
60//----------------------------------------------------------------------
61// Forward declarations / typedefs / enums
62//----------------------------------------------------------------------
63
64namespace rpc_ports
65{
66class tRPCInterface;
67template <typename T>
68class tServerPort;
69template <typename T>
70class tClientPort;
71template <typename T, bool SERVER_PORT>
72class tProxyPort;
73}
74
75namespace structure
76{
77class tConveniencePortBase;
78template <typename TPort>
79class tBasicConveniencePort;
80}
81
82namespace composite_ports
83{
84namespace internal
85{
86
87enum tPortTypeRelation
88{
89  ePTR_INPUT,
90  ePTR_OUTPUT,
91  ePTR_PARAMETER,
92  ePTR_COUNTER_PART,
93  ePTR_COUNTER_PART_PARAMETER_IF_INPUT,
94  ePTR_SERVER_IF_INPUT,
95  ePTR_CLIENT_IF_INPUT,
96  ePTR_DIMENSION
97};
98
99template <int Tprimary_interface_relations, template <typename> class TPortType, typename T, bool Trpc, bool Tdirection_specified>
100class tGenericPortType;
101
102//----------------------------------------------------------------------
103// Function declarations
104//----------------------------------------------------------------------
105
106class tTestType : public rrlib::serialization::tMemoryBuffer
107#ifdef _LIB_FINROC_PLUGINS_RPC_PORTS_PRESENT_
108  , public rpc_ports::tRPCInterface
109#endif
110{};
111
112template <template <typename> class TPortType>
113struct IsRPCPort
114{
115  enum { value = (!std::is_base_of<data_ports::tPort<tTestType>, TPortType<tTestType>>::value) && (!std::is_base_of<parameters::tParameter<tTestType>, TPortType<tTestType>>::value) };
116};
117
118template <template <typename> class TPortType>
119struct IsConveniencePort
120{
121  enum { value = std::is_base_of<structure::tConveniencePortBase, TPortType<tTestType>>::value };
122};
123
124template <template <typename> class TPortType, bool Trpc = IsRPCPort<TPortType>::value>
125struct IsOutputPort
126{
127  enum { value = std::is_base_of<data_ports::tOutputPort<double>, TPortType<double>>::value  ||
128         std::is_base_of<data_ports::tProxyPort<double, true>, TPortType<double>>::value
129       };
130};
131template <template <typename> class TPortType>
132struct IsOutputPort<TPortType, true>
133{
134  enum { value = std::is_base_of<rpc_ports::tClientPort<tTestType>, TPortType<tTestType>>::value ||
135         std::is_base_of<rpc_ports::tProxyPort<tTestType, false>, TPortType<tTestType>>::value
136       };
137};
138
139template <template <typename> class TPortType, bool Trpc = IsRPCPort<TPortType>::value>
140struct IsInputPort
141{
142  enum { value = std::is_base_of<data_ports::tInputPort<double>, TPortType<double>>::value ||
143         std::is_base_of<data_ports::tProxyPort<double, false>, TPortType<double>>::value ||
144         std::is_base_of<parameters::tParameter<double>, TPortType<double>>::value
145       };
146};
147template <template <typename> class TPortType>
148struct IsInputPort<TPortType, true>
149{
150  enum { value = std::is_base_of<rpc_ports::tServerPort<tTestType>, TPortType<tTestType>>::value ||
151         std::is_base_of<rpc_ports::tProxyPort<tTestType, true>, TPortType<tTestType>>::value
152       };
153};
154
155
156template <template <typename> class TPort, bool Trpc = IsRPCPort<TPort>::value>
157struct MakeInputPortImplementation
158{
159  template <typename T>
160  using base_type = typename std::conditional < std::is_base_of<data_ports::tProxyPort<tTestType, false>, TPort<tTestType>>::value || std::is_base_of<data_ports::tProxyPort<tTestType, true>, TPort<tTestType>>::value, data_ports::tProxyPort<T, false>, data_ports::tInputPort<T >>::type;
161
162  template <typename T>
163  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
164};
165template <template <typename> class TPort>
166struct MakeInputPortImplementation<TPort, true>
167{
168  template <typename T>
169  using base_type = typename std::conditional < std::is_base_of<rpc_ports::tServerPort<tTestType>, TPort<tTestType>>::value || std::is_base_of<rpc_ports::tClientPort<tTestType>, TPort<tTestType>>::value, rpc_ports::tServerPort<T>, rpc_ports::tProxyPort<T, true >>::type;
170
171  template <typename T>
172  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
173};
174template <template <typename> class TPort>
175using MakeInputPort = MakeInputPortImplementation<TPort>;
176
177template <template <typename> class TPort, bool Trpc = IsRPCPort<TPort>::value>
178struct MakeOutputPortImplementation
179{
180  template <typename T>
181  using base_type = typename std::conditional < std::is_base_of<data_ports::tProxyPort<tTestType, false>, TPort<tTestType>>::value || std::is_base_of<data_ports::tProxyPort<tTestType, true>, TPort<tTestType>>::value, data_ports::tProxyPort<T, true>, data_ports::tOutputPort<T >>::type;
182
183  template <typename T>
184  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
185};
186template <template <typename> class TPort>
187struct MakeOutputPortImplementation<TPort, true>
188{
189  template <typename T>
190  using base_type = typename std::conditional < std::is_base_of<rpc_ports::tClientPort<tTestType>, TPort<tTestType>>::value || std::is_base_of<rpc_ports::tClientPort<tTestType>, TPort<tTestType>>::value, rpc_ports::tClientPort<T>, rpc_ports::tProxyPort<T, false >>::type;
191
192  template <typename T>
193  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
194};
195template <template <typename> class TPort>
196using MakeOutputPort = MakeOutputPortImplementation<TPort>;
197
198template <template <typename> class TPort>
199struct MakeParameter
200{
201  template <typename T>
202  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<parameters::tParameter<T>>, parameters::tParameter<T>>::type;
203};
204
205template <template <typename> class TPort, bool Tpossibly_parameter, bool Tinput = IsInputPort<TPort>::value, bool Toutput = IsOutputPort<TPort>::value>
206struct MakeCounterDirectionPort
207{
208  template <typename T>
209  using type = data_ports::tPort<T>;
210};
211template <template <typename> class TPort, bool Tpossibly_parameter>
212struct MakeCounterDirectionPort<TPort, Tpossibly_parameter, true, false>
213{
214  template <typename T>
215  using type = typename MakeOutputPort<TPort>::template type<T>;
216};
217template <template <typename> class TPort>
218struct MakeCounterDirectionPort<TPort, false, false, true>
219{
220  template <typename T>
221  using type = typename MakeInputPort<TPort>::template type<T>;
222};
223template <template <typename> class TPort>
224struct MakeCounterDirectionPort<TPort, true, false, true> : MakeParameter<TPort>
225{
226};
227template <template <typename> class TPort>
228using MakeCounterPart = MakeCounterDirectionPort<TPort, false>;
229template <template <typename> class TPort>
230using MakeCounterPartParameterIfInput = MakeCounterDirectionPort<TPort, true>;
231
232template <template <typename> class TPort, bool TServer, bool TClient>
233struct MakeRPCPort
234{
235  template <typename T>
236  using type = core::tPortWrapperBase;
237};
238template <template <typename> class TPort>
239struct MakeRPCPort<TPort, false, true>
240{
241  template <typename T>
242  using base_type = typename std::conditional < std::is_base_of<data_ports::tProxyPort<tTestType, false>, TPort<tTestType>>::value || std::is_base_of<data_ports::tProxyPort<tTestType, true>, TPort<tTestType>>::value, rpc_ports::tProxyPort<T, false>, rpc_ports::tClientPort<T >>::type;
243
244  template <typename T>
245  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
246};
247template <template <typename> class TPort>
248struct MakeRPCPort<TPort, true, false>
249{
250  template <typename T>
251  using base_type = typename std::conditional < std::is_base_of<data_ports::tProxyPort<tTestType, false>, TPort<tTestType>>::value || std::is_base_of<data_ports::tProxyPort<tTestType, true>, TPort<tTestType>>::value, rpc_ports::tProxyPort<T, true>, rpc_ports::tServerPort<T >>::type;
252
253  template <typename T>
254  using type = typename std::conditional<IsConveniencePort<TPort>::value, structure::tBasicConveniencePort<base_type<T>>, base_type<T>>::type;
255};
256
257template <template <typename> class TPort>
258using MakeServerIfInput = MakeRPCPort<TPort, IsInputPort<TPort>::value, IsOutputPort<TPort>::value>;
259template <template <typename> class TPort>
260using MakeClientIfInput = MakeRPCPort<TPort, IsOutputPort<TPort>::value, IsInputPort<TPort>::value>;
261
262
263template <typename TPort>
264struct GetRelationId
265{
266  enum { value = 0 };
267};
268template <int Tprimary_interface_relations, template <typename> class TPortType, typename T, bool Trpc, bool Tdirection_specified>
269struct GetRelationId<tGenericPortType<Tprimary_interface_relations, TPortType, T, Trpc, Tdirection_specified>>
270{
271  enum { value = Tprimary_interface_relations };
272};
273
274template <int Trelation_id, template <typename> class TReferencePort, template <template <typename> class> class TBasePort>
275struct PrimaryPortRelation
276{
277  template <typename T>
278  using base_port = typename TBasePort<TReferencePort>::template type<T>;
279
280  template <typename T>
281  using type = tGenericPortType < GetRelationId<TReferencePort<double>>::value * 256 + Trelation_id, base_port, T, IsRPCPort<base_port>::value, IsInputPort<base_port>::value || IsOutputPort<base_port>::value >;
282};
283
284
285//----------------------------------------------------------------------
286// End of namespace declaration
287//----------------------------------------------------------------------
288}
289}
290}
291
292
293#endif
Note: See TracBrowser for help on using the repository browser.