@@ -198,7 +198,10 @@ template <stdx::ct_string Name, typename... Fields> class msg_access {
198
198
using FieldsTuple =
199
199
decltype (stdx::make_indexed_tuple<name_for>(Fields{}...));
200
200
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>;
202
205
constexpr auto belongs = (std::is_same_v<typename Field::field_id,
203
206
typename Fields::field_id> or
204
207
...);
@@ -209,20 +212,20 @@ template <stdx::ct_string Name, typename... Fields> class msg_access {
209
212
210
213
template <stdx::range R, some_field_value V>
211
214
constexpr static auto set1 (R &&r, V v) -> void {
215
+ check<name_for<V>, std::remove_cvref_t <R>>();
212
216
using Field = field_t <name_for<V>>;
213
- check<Field, std::remove_cvref_t <R>>();
214
217
Field::insert (std::forward<R>(r),
215
218
static_cast <typename Field::value_type>(v.value ));
216
219
}
217
220
218
221
template <typename N, stdx::range R>
219
222
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>>();
221
224
field_t <N>::insert_default (std::forward<R>(r));
222
225
}
223
226
224
227
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>>();
226
229
return field_t <N>::extract (std::forward<R>(r));
227
230
}
228
231
@@ -341,11 +344,36 @@ template <stdx::ct_string Name, typename Access, typename T> struct msg_base {
341
344
[[nodiscard]] constexpr auto get (auto f) const {
342
345
return Access::get (as_derived ().data (), f);
343
346
}
347
+
344
348
constexpr auto set (auto ... fs) -> void {
345
349
Access::set (as_derived ().data (), fs...);
346
350
}
347
351
constexpr auto set () -> void {}
348
352
353
+ template <stdx::ct_string N> struct proxy {
354
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members)
355
+ msg_base &b;
356
+
357
+ // NOLINTNEXTLINE(misc-unconventional-assign-operator)
358
+ constexpr auto operator =(auto val) const && -> void {
359
+ b.set (field_name<N>{} = val);
360
+ }
361
+
362
+ using V = decltype (b.get(std::declval<field_name<N>>()));
363
+
364
+ // NOLINTNEXTLINE(google-explicit-constructor)
365
+ constexpr operator V () const { return b.get (field_name<N>{}); }
366
+ };
367
+
368
+ template <stdx::ct_string N>
369
+ [[nodiscard]] constexpr auto operator [](field_name<N> f) const {
370
+ return get (f);
371
+ }
372
+ template <stdx::ct_string N>
373
+ [[nodiscard]] constexpr auto operator [](field_name<N>) LIFETIMEBOUND {
374
+ return proxy<N>{*this };
375
+ }
376
+
349
377
[[nodiscard]] constexpr auto describe () const {
350
378
return Access::describe (as_derived ().data ());
351
379
}
0 commit comments