Skip to content

Commit bf31a30

Browse files
committed
🚸 Add fail tests for field not being in message
Problem: - When a field is not in a message, trying to access it can give an help message from inside `stdx::tuple` instead of a nicer message. Solution: - Give a nicer help message when trying to access a named field that isn't in a message.
1 parent 3622553 commit bf31a30

File tree

4 files changed

+45
-4
lines changed

4 files changed

+45
-4
lines changed

include/msg/message.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ template <stdx::ct_string Name, typename... Fields> class msg_access {
198198
using FieldsTuple =
199199
decltype(stdx::make_indexed_tuple<name_for>(Fields{}...));
200200

201-
template <typename Field, stdx::range R> constexpr static auto check() {
201+
template <typename N, stdx::range R> constexpr static auto check() {
202+
static_assert((std::is_same_v<N, name_for<Fields>> or ...),
203+
"Field does not belong to this message!");
204+
using Field = field_t<N>;
202205
constexpr auto belongs = (std::is_same_v<typename Field::field_id,
203206
typename Fields::field_id> or
204207
...);
@@ -209,20 +212,20 @@ template <stdx::ct_string Name, typename... Fields> class msg_access {
209212

210213
template <stdx::range R, some_field_value V>
211214
constexpr static auto set1(R &&r, V v) -> void {
215+
check<name_for<V>, std::remove_cvref_t<R>>();
212216
using Field = field_t<name_for<V>>;
213-
check<Field, std::remove_cvref_t<R>>();
214217
Field::insert(std::forward<R>(r),
215218
static_cast<typename Field::value_type>(v.value));
216219
}
217220

218221
template <typename N, stdx::range R>
219222
constexpr static auto set_default(R &&r) -> void {
220-
check<field_t<N>, std::remove_cvref_t<R>>();
223+
check<N, std::remove_cvref_t<R>>();
221224
field_t<N>::insert_default(std::forward<R>(r));
222225
}
223226

224227
template <typename N, stdx::range R> constexpr static auto get(R &&r) {
225-
check<field_t<N>, std::remove_cvref_t<R>>();
228+
check<N, std::remove_cvref_t<R>>();
226229
return field_t<N>::extract(std::forward<R>(r));
227230
}
228231

test/msg/fail/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ add_compile_fail_test(message_cmp_view.cpp LIBRARIES warnings cib_msg)
1313
add_compile_fail_test(message_const_field_write.cpp LIBRARIES warnings cib_msg)
1414
add_compile_fail_test(message_dangling_view.cpp LIBRARIES warnings cib_msg)
1515
add_compile_fail_test(message_dup_fieldnames.cpp LIBRARIES warnings cib_msg)
16+
add_compile_fail_test(message_get_nonexistent_field.cpp LIBRARIES warnings
17+
cib_msg)
1618
add_compile_fail_test(message_incompatible_matcher.cpp LIBRARIES warnings
1719
cib_msg)
20+
add_compile_fail_test(message_set_nonexistent_field.cpp LIBRARIES warnings
21+
cib_msg)
1822
add_compile_fail_test(message_uninitialized_field.cpp LIBRARIES warnings
1923
cib_msg)
2024
add_compile_fail_test(view_upsize.cpp LIBRARIES warnings cib_msg)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <msg/field.hpp>
2+
#include <msg/message.hpp>
3+
4+
// EXPECT: Field does not belong to this message
5+
namespace {
6+
using namespace msg;
7+
8+
using test_field1 =
9+
field<"test_field", std::uint32_t>::located<at{0_dw, 31_msb, 24_lsb}>;
10+
11+
using msg_defn = message<"test_msg", test_field1>;
12+
} // namespace
13+
14+
auto main() -> int {
15+
owning<msg_defn> m{};
16+
[[maybe_unused]] auto f = m.get("no"_field);
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <msg/field.hpp>
2+
#include <msg/message.hpp>
3+
4+
// EXPECT: Field does not belong to this message
5+
namespace {
6+
using namespace msg;
7+
8+
using test_field1 =
9+
field<"test_field", std::uint32_t>::located<at{0_dw, 31_msb, 24_lsb}>;
10+
11+
using msg_defn = message<"test_msg", test_field1>;
12+
} // namespace
13+
14+
auto main() -> int {
15+
owning<msg_defn> m{};
16+
m.set("no"_field = 1);
17+
}

0 commit comments

Comments
 (0)