Skip to content

Commit 9ff800c

Browse files
filipe-cuimrolandreichweinbmw
authored andcommitted
Use if constexpr instead of sfinae where possible
1 parent 5928fc4 commit 9ff800c

3 files changed

Lines changed: 57 additions & 103 deletions

File tree

libs/bsw/middleware/include/middleware/core/MessagePayloadBuilder.h

Lines changed: 40 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -41,51 +41,34 @@ class MessagePayloadBuilder final
4141
* \param numberOfReferences Number of references sharing this payload (1 = unique)
4242
* \return HRESULT indicating success or failure
4343
*/
44-
/// Non-trivially copyable types: externally allocated + serialized.
45-
template<
46-
typename T,
47-
typename etl::enable_if<!etl::is_trivially_copyable<T>::value, int>::type = 0>
44+
template<typename T>
4845
[[nodiscard]] HRESULT
4946
allocate(T const& obj, Message& msg, uint8_t const numberOfReferences = 1U)
5047
{
51-
HRESULT ret = HRESULT::CannotAllocatePayload;
52-
53-
size_t const payloadSize = T::AllocationPolicy::getNeededSize(obj);
54-
etl::optional<etl::span<uint8_t>> buffer
55-
= allocateNonTrivialType(payloadSize, msg, numberOfReferences);
56-
if (buffer.has_value())
48+
if constexpr (!etl::is_trivially_copyable_v<T>)
5749
{
58-
T::AllocationPolicy::serialize(obj, buffer.value());
59-
ret = HRESULT::Ok;
50+
HRESULT ret = HRESULT::CannotAllocatePayload;
51+
52+
size_t const payloadSize = T::AllocationPolicy::getNeededSize(obj);
53+
etl::optional<etl::span<uint8_t>> buffer
54+
= allocateNonTrivialType(payloadSize, msg, numberOfReferences);
55+
if (buffer.has_value())
56+
{
57+
T::AllocationPolicy::serialize(obj, buffer.value());
58+
ret = HRESULT::Ok;
59+
}
60+
61+
return ret;
62+
}
63+
else if constexpr (sizeof(T) <= Message::MAX_PAYLOAD_SIZE)
64+
{
65+
msg.constructObjectAtPayload(obj);
66+
return HRESULT::Ok;
67+
}
68+
else
69+
{
70+
return allocateTrivialType(&obj, sizeof(obj), msg, numberOfReferences);
6071
}
61-
62-
return ret;
63-
}
64-
65-
/// Small trivially copyable types: stored in internal buffer.
66-
template<
67-
typename T,
68-
typename etl::enable_if<
69-
etl::is_trivially_copyable<T>::value && (sizeof(T) <= Message::MAX_PAYLOAD_SIZE),
70-
int>::type
71-
= 0>
72-
[[nodiscard]] HRESULT allocate(T const& obj, Message& msg, uint8_t const = 1U)
73-
{
74-
msg.constructObjectAtPayload(obj);
75-
return HRESULT::Ok;
76-
}
77-
78-
/// Large trivially copyable types: externally allocated.
79-
template<
80-
typename T,
81-
typename etl::enable_if<
82-
etl::is_trivially_copyable<T>::value && (sizeof(T) > Message::MAX_PAYLOAD_SIZE),
83-
int>::type
84-
= 0>
85-
[[nodiscard]] HRESULT
86-
allocate(T const& obj, Message& msg, uint8_t const numberOfReferences = 1U)
87-
{
88-
return allocateTrivialType(&obj, sizeof(obj), msg, numberOfReferences);
8972
}
9073

9174
/**
@@ -96,20 +79,6 @@ class MessagePayloadBuilder final
9679
* \param numberOfReferences Number of shared references
9780
* \return HRESULT indicating success or failure
9881
*/
99-
[[nodiscard]] HRESULT
100-
allocate(etl::span<uint8_t> const span, Message& msg, uint8_t const numberOfReferences = 1U)
101-
{
102-
return allocate(static_cast<etl::span<uint8_t const>>(span), msg, numberOfReferences);
103-
}
104-
105-
/**
106-
* Specialization for const byte spans to copy the span's data contents.
107-
*
108-
* \param span Span of const bytes to copy into the message
109-
* \param msg The message to store the payload in
110-
* \param numberOfReferences Number of shared references
111-
* \return HRESULT indicating success or failure
112-
*/
11382
[[nodiscard]] HRESULT allocate(
11483
etl::span<uint8_t const> const span, Message& msg, uint8_t const numberOfReferences = 1U)
11584
{
@@ -118,10 +87,7 @@ class MessagePayloadBuilder final
11887
msg.copyRawBytesToPayload(span);
11988
return HRESULT::Ok;
12089
}
121-
else
122-
{
123-
return allocateTrivialType(span.data(), span.size_bytes(), msg, numberOfReferences);
124-
}
90+
return allocateTrivialType(span.data(), span.size_bytes(), msg, numberOfReferences);
12591
}
12692

12793
/**
@@ -131,41 +97,25 @@ class MessagePayloadBuilder final
13197
* \param msg The message containing the payload
13298
* \return The deserialized object
13399
*/
134-
/// Non-trivially copyable types: deserialize from external allocation.
135-
template<
136-
typename T,
137-
typename etl::enable_if<!etl::is_trivially_copyable<T>::value, int>::type = 0>
138-
T readPayload(Message const& msg)
139-
{
140-
uint8_t* ptr = getAllocatorPointerFromMessage(msg);
141-
T obj = T::AllocationPolicy::deserialize(etl::span<uint8_t>(ptr, msg.getPayloadSize()));
142-
143-
return obj;
144-
}
145-
146-
/// Small trivially copyable types: read from internal buffer.
147-
template<
148-
typename T,
149-
typename etl::enable_if<
150-
etl::is_trivially_copyable<T>::value && (sizeof(T) <= Message::MAX_PAYLOAD_SIZE),
151-
int>::type
152-
= 0>
100+
template<typename T>
153101
T readPayload(Message const& msg)
154102
{
155-
return msg.getObjectStoredInPayload<T>();
156-
}
103+
if constexpr (!etl::is_trivially_copyable_v<T>)
104+
{
105+
uint8_t* ptr = getAllocatorPointerFromMessage(msg);
106+
T obj = T::AllocationPolicy::deserialize(etl::span<uint8_t>(ptr, msg.getPayloadSize()));
157107

158-
/// Large trivially copyable types: read from external allocation.
159-
template<
160-
typename T,
161-
typename etl::enable_if<
162-
etl::is_trivially_copyable<T>::value && (sizeof(T) > Message::MAX_PAYLOAD_SIZE),
163-
int>::type
164-
= 0>
165-
T readPayload(Message const& msg)
166-
{
167-
uint8_t* ptr = getAllocatorPointerFromMessage(msg);
168-
return etl::get_object_at<T>(ptr);
108+
return obj;
109+
}
110+
else if constexpr (sizeof(T) <= Message::MAX_PAYLOAD_SIZE)
111+
{
112+
return msg.getObjectStoredInPayload<T>();
113+
}
114+
else
115+
{
116+
uint8_t* ptr = getAllocatorPointerFromMessage(msg);
117+
return etl::get_object_at<T>(ptr);
118+
}
169119
}
170120

171121
/**

libs/bsw/middleware/include/middleware/core/ProxyEventBase.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,18 @@ class ProxyEventBase
6969
void unsetReceiveHandler() noexcept { _cbk = OnFieldChangedCallback(); }
7070

7171
private:
72-
template<typename E = EventType, typename etl::enable_if<etl::is_void<E>::value, int>::type = 0>
73-
void setEvent_(Message const& /* msg */) const
72+
void setEvent_([[maybe_unused]] Message const& msg) const
7473
{
75-
_cbk.call_if();
76-
}
77-
78-
template<
79-
typename E = EventType,
80-
typename etl::enable_if<!etl::is_void<E>::value, int>::type = 0>
81-
void setEvent_(Message const& msg) const
82-
{
83-
E const& data = MessagePayloadBuilder::getInstance().template readPayload<E>(msg);
84-
_cbk.call_if(data);
74+
if constexpr (etl::is_void_v<EventType>)
75+
{
76+
_cbk.call_if();
77+
}
78+
else
79+
{
80+
EventType const& data
81+
= MessagePayloadBuilder::getInstance().readPayload<EventType>(msg);
82+
_cbk.call_if(data);
83+
}
8584
}
8685

8786
OnFieldChangedCallback _cbk;

libs/bsw/middleware/test/src/core/FutureDispatcherTest.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ void callUpdateTimeouts(Dispatcher&, long)
253253
TYPED_TEST(FutureDispatcherTestSuite, TestTimeoutDispatching)
254254
{
255255
using TraitsUnderTest = typename TypeParam::TraitsUnderTest;
256-
if (TraitsUnderTest::TIMEOUT_VALUE > 0U)
256+
if constexpr (TraitsUnderTest::TIMEOUT_VALUE > 0U)
257257
{
258258
using RefApp = typename TestFixture::RefApp;
259259
etl::optional<uint16_t> requestId{};
@@ -276,6 +276,11 @@ TYPED_TEST(FutureDispatcherTestSuite, TestTimeoutDispatching)
276276
callUpdateTimeouts(*this, 0);
277277
}
278278
}
279+
else
280+
{
281+
GTEST_SKIP() << "Test should only run for dispatchers that contain future objects with "
282+
"timeouts bigger than 0.";
283+
}
279284
}
280285

281286
TYPED_TEST(FutureDispatcherTestSuite, TestRequestIdWraparound)

0 commit comments

Comments
 (0)