Compute Graph Framework SDK Reference  5.16
PortDescriptor.hpp
Go to the documentation of this file.
1
2//
3// Notice
4// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
5// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
6// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
7// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8//
9// NVIDIA CORPORATION & AFFILIATES assumes no responsibility for the consequences of use of such
10// information or for any infringement of patents or other rights of third parties that may
11// result from its use. No license is granted by implication or otherwise under any patent
12// or patent rights of NVIDIA CORPORATION & AFFILIATES. No third party distribution is allowed unless
13// expressly authorized by NVIDIA. Details are subject to change without notice.
14// This code supersedes and replaces all information previously supplied.
15// NVIDIA CORPORATION & AFFILIATES products are not authorized for use as critical
16// components in life support devices or systems without express written approval of
17// NVIDIA CORPORATION & AFFILIATES.
18//
19// SPDX-FileCopyrightText: Copyright (c) 2021-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
20// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
21//
22// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
23// property and proprietary rights in and to this material, related
24// documentation and any modifications thereto. Any use, reproduction,
25// disclosure or distribution of this material and related documentation
26// without an express license agreement from NVIDIA CORPORATION or
27// its affiliates is strictly prohibited.
28//
30
31#ifndef DW_FRAMEWORK_PORTDESCRIPTOR_HPP_
32#define DW_FRAMEWORK_PORTDESCRIPTOR_HPP_
33
34#include <dwshared/dwfoundation/dw/core/container/StringView.hpp>
35#include <dwcgf/port/Port.hpp>
36#include <dwshared/dwfoundation/dw/core/language/cxx20.hpp>
37#include <dwshared/dwfoundation/dw/core/language/Tuple.hpp>
38#include <dwshared/dwfoundation/dw/core/safety/Safety.hpp>
39
40#include <functional>
41#include <type_traits>
42#include <utility>
43
44namespace dw
45{
46namespace framework
47{
48
49// API needed to declare the ports of a node.
50
51template <typename... Args>
52// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
53constexpr auto describePortCollection(Args&&... args) -> dw::core::Tuple<Args...>
54{
55 return dw::core::make_tuple<Args...>(std::forward<Args>(args)...);
56}
57
58enum class PortBinding : uint8_t
59{
60 OPTIONAL = 0,
61 REQUIRED = 1
62};
63
64// coverity[autosar_cpp14_a14_1_1_violation]
65template <typename PortType, size_t ArraySize, size_t NameSize>
67{
68 // coverity[autosar_cpp14_a0_1_6_violation]
69 using Type = PortType;
70 dw::core::StringView typeName;
71 dw::core::StringView name;
72 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
73 static constexpr size_t arraySize{ArraySize};
74 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
75 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
76 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
77 static constexpr size_t nameSize{NameSize};
79 dw::core::StringView comment;
80
81 constexpr PortDescriptorT(dw::core::StringView&& typeName_, dw::core::StringView&& name_, PortBinding binding_ = PortBinding::OPTIONAL, dw::core::StringView comment_ = ""_sv)
82 : typeName{std::move(typeName_)}
83 , name{std::move(name_)}
84 , binding{std::move(binding_)}
85 , comment{std::move(comment_)}
86 {
87 }
88};
89
90#define DW_PORT_TYPE_NAME_STRING_VIEW_IMPL(TYPE_NAME_STR) TYPE_NAME_STR##_sv
91#define DW_PORT_TYPE_NAME_STRING_VIEW(TYPE_NAME) DW_PORT_TYPE_NAME_STRING_VIEW_IMPL(#TYPE_NAME)
92#define DW_DESCRIBE_PORT(TYPE_NAME, NAME, args...) dw::framework::describePort<TYPE_NAME, NAME.size()>(DW_PORT_TYPE_NAME_STRING_VIEW(TYPE_NAME), NAME, ##args)
93
94template <typename PortType, size_t NameSize>
95// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
96constexpr auto describePort(
97 dw::core::StringView typeName, dw::core::StringView name, PortBinding binding = PortBinding::OPTIONAL, dw::core::StringView comment = ""_sv) -> PortDescriptorT<PortType, 0, NameSize>
98{
100 std::move(typeName),
101 std::move(name),
102 std::move(binding),
103 std::move(comment));
104}
105
106template <typename PortType, size_t NameSize>
107// Overloaded functions are provided for ease of use
108// coverity[autosar_cpp14_a2_10_5_violation]
109constexpr auto describePort(
110 dw::core::StringView typeName, dw::core::StringView name, dw::core::StringView comment)
111{
112 return describePort<PortType, NameSize>(
113 std::move(typeName),
114 std::move(name),
115 std::move(PortBinding::OPTIONAL),
116 std::move(comment));
117}
118
119#define DW_DESCRIBE_PORT_ARRAY(TYPE_NAME, ARRAYSIZE, NAME, args...) dw::framework::describePortArray<TYPE_NAME, ARRAYSIZE, NAME.size()>(DW_PORT_TYPE_NAME_STRING_VIEW(TYPE_NAME), NAME, ##args)
120template <
121 typename PortType,
122 size_t ArraySize,
123 size_t NameSize,
124 typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
125// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
126constexpr auto describePortArray(
127 dw::core::StringView typeName, dw::core::StringView name, PortBinding binding = PortBinding::OPTIONAL, dw::core::StringView comment = ""_sv) -> PortDescriptorT<PortType, ArraySize, NameSize>
128{
130 std::move(typeName),
131 std::move(name),
132 std::move(binding),
133 std::move(comment));
134}
135
136template <
137 typename PortType,
138 size_t ArraySize,
139 size_t NameSize,
140 typename std::enable_if_t<ArraySize != 0, void>* = nullptr>
141// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
142constexpr auto describePortArray(
143 dw::core::StringView typeName, dw::core::StringView name, dw::core::StringView comment)
144{
145 return describePortArray<PortType, ArraySize, NameSize>(
146 std::move(typeName),
147 std::move(name),
148 std::move(PortBinding::OPTIONAL),
149 std::move(comment));
150}
151
152// API to access declared ports of a node.
153
154// LCOV_EXCL_START no coverage data for compile time evaluated function
155template <typename Node>
156// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
157// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
159{
160 return Node::describeInputPorts();
161}
162// LCOV_EXCL_STOP
163
164template <typename Node>
165// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
166// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
168{
169 return Node::describeOutputPorts();
170}
171
172// LCOV_EXCL_START no coverage data for compile time evaluated function
173template <
174 typename Node,
175 PortDirection Direction,
176 typename std::enable_if_t<Direction == PortDirection::INPUT, void>* = nullptr>
177// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
178// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
179constexpr auto describePorts()
180{
181 return describeNodeInputPorts<Node>();
182}
183// LCOV_EXCL_STOP
184
185template <
186 typename Node,
187 PortDirection Direction,
188 typename std::enable_if_t<Direction == PortDirection::OUTPUT, void>* = nullptr>
189// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
190// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
191constexpr auto describePorts()
192{
193 return describeNodeOutputPorts<Node>();
194}
195
196// API to query information about declared ports of a node.
197
198// Number of input or output port descriptors
199template <typename Node, PortDirection Direction>
200// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
201constexpr std::size_t portDescriptorSize()
202{
203 return dw::core::tuple_size<decltype(describePorts<Node, Direction>())>::value;
204}
205
206// The flag if the port described by a specific descriptor is an array
207template <typename Node, PortDirection Direction, size_t DescriptorIndex>
208constexpr bool descriptorPortArray()
209{
210 constexpr size_t array_length{dw::core::tuple_element_t<
211 DescriptorIndex,
212 decltype(describePorts<Node, Direction>())>::arraySize};
213 return array_length > 0;
214}
215
216// The number of input or output ports described by a specific descriptor
217// 1 for non-array descriptors, ARRAY_SIZE for array descriptors
218template <typename Node, PortDirection Direction, size_t DescriptorIndex>
219// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
220constexpr size_t descriptorPortSize()
221{
222 constexpr size_t array_length{dw::core::tuple_element_t<
223 DescriptorIndex,
224 decltype(describePorts<Node, Direction>())>::arraySize};
225 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
226 if (0U == array_length)
227 {
228 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
229 return 1U;
230 }
231 return array_length;
232}
233
234// The binding of input or output ports described by a specific descriptor
235template <typename Node, PortDirection Direction, size_t DescriptorIndex>
237{
238 constexpr PortBinding port_binding = dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()).binding;
239 return port_binding;
240}
241
242// The comment of input or output ports described by a specific descriptor
243template <typename Node, PortDirection Direction, size_t DescriptorIndex>
244constexpr dw::core::StringView descriptorPortComment()
245{
246 constexpr dw::core::StringView port_comment = dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()).comment;
247 return port_comment;
248}
249
250// Return type is the type of the descriptor, to be used with decltype()
251template <typename Node, PortDirection Direction, size_t DescriptorIndex>
252// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
253// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
254constexpr auto portDescriptorType()
255{
256 return typename dw::core::tuple_element_t<
257 DescriptorIndex,
258 decltype(describePorts<Node, Direction>())>::Type();
259}
260
261// Number of ports for a specific direction (sum across all descriptors)
262namespace detail
263{
264
265template <
266 typename Node, PortDirection Direction, size_t DescriptorIndex,
267 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
268// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
269constexpr std::size_t portSize_()
270{
271 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
272 return 0U;
273}
274
275template <
276 typename Node, PortDirection Direction, size_t DescriptorIndex,
277 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr>
278 // coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
279 constexpr std::size_t portSize_()
280{
281 return descriptorPortSize<Node, Direction, DescriptorIndex>() + portSize_<Node, Direction, DescriptorIndex + 1>();
282}
283
284} // namespace detail
285
286template <typename Node, PortDirection Direction>
287// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
288constexpr std::size_t portSize()
289{
290 return detail::portSize_<Node, Direction, 0>();
291}
292
293// Descriptor index from port index
294namespace detail
295{
296
297template <
298 typename Node, PortDirection Direction, size_t DescriptorIndex, size_t RemainingPortIndex,
299 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
300// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
301constexpr std::size_t descriptorIndex_()
302{
303 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
304 return 0U;
305}
306
307template <
308 typename Node, PortDirection Direction, size_t DescriptorIndex, size_t RemainingPortIndex,
309 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr>
310 // coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
311 constexpr std::size_t descriptorIndex_()
312{
313 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
314 if (RemainingPortIndex < descriptorPortSize<Node, Direction, DescriptorIndex>())
315 {
316 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
317 return 0U;
318 }
319 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
320 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
321 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
322 constexpr size_t remainingPortIndex{RemainingPortIndex - descriptorPortSize<Node, Direction, DescriptorIndex>()};
323 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
324 return 1U + descriptorIndex_<Node, Direction, DescriptorIndex + 1, remainingPortIndex>();
325}
326
327} // namespace detail
328
329template <typename Node, PortDirection Direction, size_t PortIndex>
330// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
331constexpr size_t descriptorIndex()
332{
333 if (PortDirection::OUTPUT == Direction)
334 {
335 return detail::descriptorIndex_<Node, Direction, 0, PortIndex - portSize<Node, PortDirection::INPUT>()>();
336 }
337 return detail::descriptorIndex_<Node, Direction, 0, PortIndex>();
338}
339
340template <typename Node, PortDirection Direction, size_t PortIndex>
341// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
342constexpr dw::core::StringView portName()
343{
344 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
345 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
346 constexpr size_t index{descriptorIndex<Node, Direction, PortIndex>()};
347 return dw::core::get<index>(describePorts<Node, Direction>()).name;
348}
349
350namespace detail
351{
352
353// coverity[autosar_cpp14_m3_4_1_violation]
354constexpr const size_t DECIMAL_BASE{10U};
355
356constexpr size_t numberOfDigits(size_t number)
357{
358 static_assert(std::numeric_limits<size_t>::digits10 <= std::numeric_limits<size_t>::max(), "size_t number of digits exceeds size_t (not possible)");
359 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
360 if (0U == number)
361 {
362 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
363 return 1U;
364 }
365 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
366 size_t count{0U};
367 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
368 while (number > 0U)
369 {
370 number = number / DECIMAL_BASE;
371 // coverity[autosar_cpp14_a4_7_1_violation] FP: nvbugs/2990097
372 // coverity[cert_int30_c_violation]
373 ++count;
374 }
375 return count;
376}
377
378constexpr size_t getArrayNameSize(size_t portNameSize, size_t arrayIndex)
379{
380 // port name size + '[' + number of digits of the array index + ']'
381 constexpr size_t MAX_SIZE_WITHOUT_BRACKETS{std::numeric_limits<size_t>::max() - 1U - 1U};
382 if (portNameSize >= MAX_SIZE_WITHOUT_BRACKETS)
383 {
384 throw std::runtime_error("Array name too long");
385 }
386 if (MAX_SIZE_WITHOUT_BRACKETS - portNameSize < numberOfDigits(arrayIndex))
387 {
388 throw std::runtime_error("Array name + digits for array index too long");
389 }
390 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
391 return portNameSize + 1U + numberOfDigits(arrayIndex) + 1U;
392}
393
394template <size_t NameSize, size_t ArraySize>
395// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
396constexpr size_t getMaximumArrayNameSize()
397{
398 static_assert(NameSize > 0U, "Name size must not be zero");
399 static_assert(ArraySize > 0U, "Array size must not be zero");
400 // number of digits for the largest array index
401 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
402 return getArrayNameSize(NameSize, ArraySize - 1U);
403}
404
405template <size_t NameSize, size_t ArraySize>
406class PortNamesGenerator
407{
408public:
409 static_assert(NameSize > 0U, "Name size must not be zero");
410 static_assert(ArraySize > 0U, "Array size must not be zero");
411 // same size for all names even though smaller indices might be shorter
412 // + 1 for a null character for each name to be defensive in case the string view is used incorrectly
413 static_assert(std::numeric_limits<size_t>::max() / ArraySize > getMaximumArrayNameSize<NameSize, ArraySize>() + 1U, "The storage size exceeds size_t");
414 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
415 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
416 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
417 static constexpr size_t StorageSize{ArraySize * (getMaximumArrayNameSize<NameSize, ArraySize>() + 1U)};
418 constexpr PortNamesGenerator(dw::core::StringView baseName)
419 : data()
420 {
421 if (baseName.size() > NameSize)
422 {
423 // LCOV_EXCL_START the calling code uses the size of the StringView as the template parameter
424 throw ExceptionWithStatus(DW_INTERNAL_ERROR, "The passed string size ", baseName.size(), " exceeds the template parameter NameSize ", NameSize);
425 // LCOV_EXCL_STOP
426 }
427 size_t i{0U};
428 for (size_t arrayIndex{0U}; ArraySize != arrayIndex; ++arrayIndex)
429 {
430 // copy base port name
431 for (size_t j{0U}; j < baseName.size(); ++j)
432 {
433 // coverity[cert_ctr50_cpp_violation]
434 data[i] = baseName[j];
435 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
436 dw::core::safeIncrement(i, 1U);
437 }
438
439 // append the array index wrapped in brackets
440 const char8_t OPENING_BRACKET{'['};
441 // coverity[cert_ctr50_cpp_violation]
442 data[i] = OPENING_BRACKET;
443 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
444 dw::core::safeIncrement(i, 1U);
445
446 size_t remainingValue{arrayIndex};
447 // the length of the port name isn't close to the maximum value of size_t, hence no risk of overflow
448 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
449 const size_t INDEX_LAST_DIGIT{dw::core::safeAdd(i, numberOfDigits(arrayIndex) - 1U).value()};
450 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
451 for (size_t j{0U}; j < numberOfDigits(arrayIndex); ++j)
452 {
453 // fill the array index digits in reverse order
454 constexpr char8_t digits[10]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
455 // coverity[autosar_cpp14_a4_7_1_violation] FP: nvbugs/2990097
456 // coverity[cert_int30_c_violation]
457 data[INDEX_LAST_DIGIT - j] = digits[remainingValue % DECIMAL_BASE];
458 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
459 dw::core::safeIncrement(i, 1U);
460 remainingValue = remainingValue / DECIMAL_BASE;
461 }
462
463 const char8_t CLOSING_BRACKET{']'};
464 // coverity[cert_ctr50_cpp_violation]
465 data[i] = CLOSING_BRACKET;
466 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
467 dw::core::safeIncrement(i, 1U);
468 // coverity[autosar_cpp14_a5_1_1_violation]
469 // coverity[cert_ctr50_cpp_violation]
470 data[i] = '\0';
471 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
472 dw::core::safeIncrement(i, 1U);
473 // skip delta which this name is shorter compared to the maximum length
474 // coverity[autosar_cpp14_a4_7_1_violation] FP: nvbugs/2990097
475 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
476 // coverity[cert_int30_c_violation]
477 i += numberOfDigits(ArraySize - 1U) - numberOfDigits(arrayIndex);
478 }
479 }
480
481 dw::core::StringView getName(size_t arrayIndex) const
482 {
483 if (arrayIndex >= ArraySize)
484 {
485 throw ExceptionWithStatus(DW_OUT_OF_BOUNDS, "Array index ", arrayIndex, " out of bound for array size ", ArraySize);
486 }
487 // coverity[autosar_cpp14_a5_1_1_violation] FP: nvbugs/3364868
488 return dw::core::StringView(&data[arrayIndex * (getMaximumArrayNameSize<NameSize, ArraySize>() + 1U)], getArrayNameSize(NameSize, arrayIndex));
489 }
490
491private:
492 char8_t data[StorageSize];
493};
494
495} // namespace detail
496
497template <typename Node, PortDirection Direction, size_t PortIndex>
498// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
499dw::core::StringView portName(size_t arrayIndex)
500{
501 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
502 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
503 constexpr size_t index{descriptorIndex<Node, Direction, PortIndex>()};
504 // coverity[autosar_cpp14_a8_5_3_violation]
505 constexpr auto desc{dw::core::get<index>(describePorts<Node, Direction>())};
506 static_assert(desc.arraySize > 0U, "A port name with an array index argument is only applicable to array ports");
507 // coverity[autosar_cpp14_a3_3_2_violation]
508 static const detail::PortNamesGenerator<desc.nameSize, desc.arraySize> generatedNames{desc.name};
509 return generatedNames.getName(arrayIndex);
510}
511
512// Return type is the type of the port, to be used with decltype()
513template <typename Node, PortDirection Direction, size_t PortIndex>
514// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
515// coverity[autosar_cpp14_a7_1_5_violation] RFD Pending: TID-2201
516constexpr auto portType()
517{
518 // coverity[autosar_cpp14_a0_1_1_violation] FP: nvbugs/2813925
519 // coverity[autosar_cpp14_m0_1_4_violation] FP: nvbugs/2813925
520 constexpr size_t index{descriptorIndex<Node, Direction, PortIndex>()};
521 return portDescriptorType<Node, Direction, index>();
522}
523
524// Check if port index is valid
525template <typename Node, PortDirection Direction>
526constexpr bool isValidPortIndex(std::size_t portID)
527{
528 // only temporarily for backward compatibility with enum value
529 // output port indices are offset by the number of input ports
530 if (PortDirection::OUTPUT == Direction)
531 {
532 return portID >= portSize<Node, PortDirection::INPUT>() && portID < portSize<Node, PortDirection::INPUT>() + portSize<Node, Direction>();
533 }
534 return portID < portSize<Node, Direction>();
535}
536
537// Array size for an array port name, 0 for non-array ports
538namespace detail
539{
540
541template <
542 typename Node, PortDirection Direction, size_t DescriptorIndex,
543 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
544constexpr std::size_t portArraySize_(StringView identifier)
545{
546 (void)identifier;
547 return 0;
548}
549
550template <
551 typename Node, PortDirection Direction, size_t DescriptorIndex,
552 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr>
553 // coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
554 constexpr std::size_t portArraySize_(StringView identifier)
555{
556 constexpr auto descriptorName = dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()).name;
557 if (descriptorName == identifier)
558 {
559 return descriptorPortSize<Node, Direction, DescriptorIndex>();
560 }
561 return portArraySize_<Node, Direction, DescriptorIndex + 1>(identifier);
562}
563
564} // namespace detail
565
566template <typename Node, PortDirection Direction>
567constexpr size_t portArraySize(StringView identifier)
568{
569 return detail::portArraySize_<Node, Direction, 0>(identifier);
570}
571
572// LCOV_EXCL_START no coverage data for compile time evaluated function
573// Get the port index for a give port name
574namespace detail
575{
576
577template <
578 typename Node, PortDirection Direction, size_t DescriptorIndex,
579 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
580// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
581constexpr std::size_t portIndex_(StringView identifier)
582{
583 static_cast<void>(identifier);
584 // since output port indices follow input port indices
585 // this must add the number of output port for invalid input port identifier
586 // to avoid that for an invalid input port identifier the index of the first output port is returned
587 if (PortDirection::INPUT == Direction)
588 {
589 return dw::framework::portSize<Node, PortDirection::OUTPUT>();
590 }
591 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
592 return 0U;
593}
594
595template <
596 typename Node, PortDirection Direction, size_t DescriptorIndex,
597 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr>
598 // coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
599 constexpr std::size_t portIndex_(StringView identifier)
600{
601 constexpr StringView descriptorName{dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()).name};
602 if (descriptorName == identifier)
603 {
604 // coverity[autosar_cpp14_a5_1_1_violation] RFD Accepted: TID-2056
605 return 0U;
606 }
607 return descriptorPortSize<Node, Direction, DescriptorIndex>() + portIndex_<Node, Direction, DescriptorIndex + 1>(identifier);
608}
609
610} // namespace detail
611
612template <typename Node, PortDirection Direction>
613// coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
614constexpr size_t portIndex(StringView identifier)
615{
616 // only temporarily for backward compatibility with enum value
617 // output port indices are offset by the number of input ports
618 if (PortDirection::OUTPUT == Direction)
619 {
620 return portSize<Node, PortDirection::INPUT>() + detail::portIndex_<Node, Direction, 0>(identifier);
621 }
622 return detail::portIndex_<Node, Direction, 0>(identifier);
623}
624// LCOV_EXCL_STOP
625
626// Check if given string is a valid port name
627template <typename Node, PortDirection Direction>
628constexpr bool isValidPortIdentifier(StringView identifier)
629{
630 constexpr size_t index = portIndex<Node, Direction>(identifier);
631 return isValidPortIndex<Node, Direction>(index);
632}
633
634// Get the port index for a give port name
635namespace detail
636{
637
638template <
639 typename Node, PortDirection Direction, size_t DescriptorIndex,
640 typename std::enable_if_t<DescriptorIndex == portDescriptorSize<Node, Direction>(), void>* = nullptr>
641constexpr std::size_t portDescriptorIndex_(StringView identifier)
642{
643 (void)identifier;
644 return 0;
645}
646
647template <
648 typename Node, PortDirection Direction, size_t DescriptorIndex,
649 typename std::enable_if_t<DescriptorIndex<portDescriptorSize<Node, Direction>(), void>* = nullptr>
650 // coverity[autosar_cpp14_a2_10_5_violation] FP: nvbugs/3907242
651 constexpr std::size_t portDescriptorIndex_(StringView identifier)
652{
653 constexpr auto descriptorName = dw::core::get<DescriptorIndex>(describePorts<Node, Direction>()).name;
654 if (descriptorName == identifier)
655 {
656 return 0;
657 }
658 return 1 + portDescriptorIndex_<Node, Direction, DescriptorIndex + 1>(identifier);
659}
660
661} // namespace detail
662
663template <typename Node, PortDirection Direction>
664constexpr size_t portDescriptorIndex(StringView identifier)
665{
666 return detail::portDescriptorIndex_<Node, Direction, 0>(identifier);
667}
668
669} // namespace framework
670} // namespace dw
671
672#endif // DW_FRAMEWORK_PORTDESCRIPTOR_HPP_
constexpr auto describePorts()
constexpr bool descriptorPortArray()
constexpr size_t portIndex(StringView identifier)
constexpr size_t descriptorPortSize()
constexpr auto describePortArray(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv) -> PortDescriptorT< PortType, ArraySize, NameSize >
constexpr size_t portDescriptorIndex(StringView identifier)
constexpr auto describeNodeInputPorts()
constexpr auto portDescriptorType()
constexpr auto describePort(dw::core::StringView typeName, dw::core::StringView name, PortBinding binding=PortBinding::OPTIONAL, dw::core::StringView comment=""_sv) -> PortDescriptorT< PortType, 0, NameSize >
constexpr size_t portArraySize(StringView identifier)
constexpr std::size_t portDescriptorSize()
constexpr auto describePortCollection(Args &&... args) -> dw::core::Tuple< Args... >
constexpr bool isValidPortIndex(std::size_t portID)
constexpr std::size_t portSize()
constexpr PortBinding descriptorPortBinding()
constexpr dw::core::StringView portName()
constexpr auto describeNodeOutputPorts()
constexpr bool isValidPortIdentifier(StringView identifier)
constexpr dw::core::StringView descriptorPortComment()
constexpr auto portType()
constexpr size_t descriptorIndex()
Definition: Buffer.hpp:40
static constexpr size_t arraySize
dw::core::StringView typeName
dw::core::StringView comment
constexpr PortDescriptorT(dw::core::StringView &&typeName_, dw::core::StringView &&name_, PortBinding binding_=PortBinding::OPTIONAL, dw::core::StringView comment_=""_sv)
static constexpr size_t nameSize