Skip to content

Commit 50c476b

Browse files
committed
🚸 Add operator[] to messages
Problem: - Messages support `get` and `set` but not a natural indexing syntax. Solution: - Add `operator[]` to message, so that the follow work: ```c+++ msg["a"_field] = 42; auto x = msg["a"_field]; ```
1 parent bf31a30 commit 50c476b

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

include/msg/message.hpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,11 +344,32 @@ template <stdx::ct_string Name, typename Access, typename T> struct msg_base {
344344
[[nodiscard]] constexpr auto get(auto f) const {
345345
return Access::get(as_derived().data(), f);
346346
}
347+
347348
constexpr auto set(auto... fs) -> void {
348349
Access::set(as_derived().data(), fs...);
349350
}
350351
constexpr auto set() -> void {}
351352

353+
template <stdx::ct_string N, typename B> struct proxy {
354+
B &b;
355+
constexpr auto operator=(auto val) const && -> void {
356+
b.set(field_name<N>{} = val);
357+
}
358+
359+
using V = decltype(b.get(std::declval<field_name<N>>()));
360+
constexpr operator V() const && { return b.get(field_name<N>{}); }
361+
};
362+
363+
template <stdx::ct_string N>
364+
[[nodiscard]] constexpr auto operator[](field_name<N> f) const {
365+
return get(f);
366+
}
367+
template <stdx::ct_string N>
368+
[[nodiscard]] constexpr auto
369+
operator[](field_name<N>) LIFETIMEBOUND->proxy<N, msg_base> {
370+
return {*this};
371+
}
372+
352373
[[nodiscard]] constexpr auto describe() const {
353374
return Access::describe(as_derived().data());
354375
}

test/msg/message.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,3 +792,15 @@ TEST_CASE("pack appends environments", "[message]") {
792792
using defn = pack<"defn", std::uint8_t, m1, m2>;
793793
STATIC_REQUIRE(custom(defn::env_t{}) == 18);
794794
}
795+
796+
TEST_CASE("read indexing operator on message", "[message]") {
797+
test_msg const msg{};
798+
CHECK(0x80 == msg["id"_field]);
799+
}
800+
801+
TEST_CASE("write indexing operator on message", "[message]") {
802+
test_msg msg{};
803+
CHECK((0 == msg["f1"_field]));
804+
msg["f1"_field] = 0xba11;
805+
CHECK((0xba11 == msg["f1"_field]));
806+
}

0 commit comments

Comments
 (0)