9
9
10
10
#include < stdx/compiler.hpp>
11
11
#include < stdx/ct_string.hpp>
12
- #include < stdx/cx_vector .hpp>
12
+ #include < stdx/env .hpp>
13
13
#include < stdx/iterator.hpp>
14
14
#include < stdx/ranges.hpp>
15
15
#include < stdx/span.hpp>
@@ -197,7 +197,7 @@ template <typename... Fields> struct storage_size {
197
197
198
198
template <typename F> using name_for = typename F::name_t ;
199
199
200
- template <stdx::ct_string Name, typename ... Fields> class message_access {
200
+ template <stdx::ct_string Name, typename ... Fields> class msg_access {
201
201
using FieldsTuple =
202
202
decltype (stdx::make_indexed_tuple<name_for>(Fields{}...));
203
203
@@ -295,10 +295,11 @@ concept storage_like = stdx::range<T> and requires {
295
295
typename T::value_type;
296
296
};
297
297
298
- template <stdx::ct_string Name, typename ... Fields> struct message ;
298
+ template <stdx::ct_string Name, typename Env, typename ... Fields>
299
+ struct message ;
299
300
300
- template <stdx::ct_string Name> struct msg_q {
301
- template <typename ... Fields> using fn = message<Name, Fields...>;
301
+ template <stdx::ct_string Name, typename Env > struct msg_q {
302
+ template <typename ... Fields> using fn = message<Name, Env, Fields...>;
302
303
};
303
304
304
305
template <typename F1, typename F2>
@@ -312,9 +313,9 @@ using unique_by_name = boost::mp11::mp_unique_if<
312
313
boost::mp11::mp_sort<boost::mp11::mp_list<Fields...>, field_sort_fn>,
313
314
name_equal_fn>;
314
315
315
- template <stdx::ct_string Name, typename ... Fields>
316
+ template <stdx::ct_string Name, typename Env, typename ... Fields>
316
317
using message_without_unique_field_names =
317
- boost::mp11::mp_apply_q<detail::msg_q<Name>,
318
+ boost::mp11::mp_apply_q<detail::msg_q<Name, Env >,
318
319
detail::unique_by_name<Fields...>>;
319
320
320
321
template <stdx::ct_string Name, typename ... Fields>
@@ -323,12 +324,45 @@ struct message_with_unique_field_names {
323
324
name_for, boost::mp11::mp_list<Fields...>>>::value,
324
325
" Message contains fields with duplicate names" );
325
326
326
- using type = message_without_unique_field_names<Name, Fields...>;
327
+ using type =
328
+ message_without_unique_field_names<Name, stdx::env<>, Fields...>;
329
+ };
330
+
331
+ template <stdx::ct_string Name, stdx::envlike Env, typename ... Fields>
332
+ struct message_with_unique_field_names <Name, Env, Fields...> {
333
+ static_assert (boost::mp11::mp_is_set<boost::mp11::mp_transform<
334
+ name_for, boost::mp11::mp_list<Fields...>>>::value,
335
+ " Message contains fields with duplicate names" );
336
+
337
+ using type = message_without_unique_field_names<Name, Env, Fields...>;
327
338
};
328
339
329
- template <stdx::ct_string Name, typename ... Fields> struct message {
340
+ template <stdx::ct_string Name, typename Access, typename T> struct msg_base {
341
+ constexpr static auto name = Name;
342
+
343
+ constexpr auto as_derived () const -> T const & {
344
+ return static_cast <T const &>(*this );
345
+ }
346
+ constexpr auto as_derived () -> T & { return static_cast <T &>(*this ); }
347
+
348
+ [[nodiscard]] constexpr auto get (auto f) const {
349
+ return Access::get (as_derived ().data (), f);
350
+ }
351
+ constexpr auto set (auto ... fs) -> void {
352
+ Access::set (as_derived ().data (), fs...);
353
+ }
354
+ constexpr auto set () -> void {}
355
+
356
+ [[nodiscard]] constexpr auto describe () const {
357
+ return Access::describe (as_derived ().data ());
358
+ }
359
+ };
360
+
361
+ template <stdx::ct_string Name, typename Env, typename ... Fields>
362
+ struct message {
330
363
using fields_t = stdx::type_list<Fields...>;
331
- using access_t = detail::message_access<Name, Fields...>;
364
+ using env_t = Env;
365
+ using access_t = msg_access<Name, Fields...>;
332
366
using default_storage_t = typename access_t ::default_storage_t ;
333
367
using default_span_t = typename access_t ::default_span_t ;
334
368
using default_const_span_t = typename access_t ::default_const_span_t ;
@@ -342,32 +376,13 @@ template <stdx::ct_string Name, typename... Fields> struct message {
342
376
343
377
template <auto N, typename Unit = bit_unit>
344
378
using shifted_by =
345
- message<Name, typename Fields::template shifted_by<N, Unit>...>;
379
+ message<Name, Env, typename Fields::template shifted_by<N, Unit>...>;
346
380
347
381
template <typename S>
348
382
constexpr static auto fits_inside =
349
383
(... and Fields::template fits_inside<S>());
350
384
351
- template <typename T> struct base {
352
- constexpr static auto name = Name;
353
-
354
- constexpr auto as_derived () const -> T const & {
355
- return static_cast <T const &>(*this );
356
- }
357
- constexpr auto as_derived () -> T & { return static_cast <T &>(*this ); }
358
-
359
- [[nodiscard]] constexpr auto get (auto f) const {
360
- return access_t::get (as_derived ().data (), f);
361
- }
362
- constexpr auto set (auto ... fs) -> void {
363
- access_t::set (as_derived ().data (), fs...);
364
- }
365
- constexpr auto set () -> void {}
366
-
367
- [[nodiscard]] constexpr auto describe () const {
368
- return access_t::describe (as_derived ().data ());
369
- }
370
- };
385
+ template <typename T> using base = msg_base<Name, access_t , T>;
371
386
372
387
template <typename > struct owner_t ;
373
388
@@ -583,13 +598,17 @@ template <stdx::ct_string Name, typename... Fields> struct message {
583
598
// name (see unique_by_name)
584
599
template <stdx::ct_string NewName, typename ... NewFields>
585
600
using extension =
586
- message_without_unique_field_names<NewName, NewFields..., Fields...>;
601
+ message_without_unique_field_names<NewName, Env, NewFields...,
602
+ Fields...>;
603
+
604
+ template <stdx::envlike E>
605
+ using with_env = message<Name, stdx::append_env_t <Env, E>, Fields...>;
587
606
};
588
607
} // namespace detail
589
608
590
- template <stdx::ct_string Name, typename ... Fields >
609
+ template <stdx::ct_string Name, typename ... Ts >
591
610
using message =
592
- typename detail::message_with_unique_field_names<Name, Fields ...>::type;
611
+ typename detail::message_with_unique_field_names<Name, Ts ...>::type;
593
612
594
613
template <typename T> using owning = typename T::template owner_t <>;
595
614
template <typename T> using mutable_view = typename T::mutable_view_t ;
@@ -681,15 +700,16 @@ using shifted_msgs =
681
700
msg_offsets<AlignTo, Msgs...>,
682
701
stdx::type_list<Msgs..., msg::message<" end" >>>;
683
702
684
- template <stdx::ct_string Name> struct combiner {
685
- template <typename ... Fields> using fn = msg::message<Name, Fields...>;
703
+ template <stdx::ct_string Name, stdx::envlike Env > struct combiner {
704
+ template <typename ... Fields> using fn = msg::message<Name, Env, Fields...>;
686
705
};
687
706
688
707
template <stdx::ct_string Name> struct combine_q {
689
708
template <typename ... Msgs>
690
709
requires (sizeof ...(Msgs) > 0 )
691
710
using fn = boost::mp11::mp_apply_q<
692
- combiner<Name>, boost::mp11::mp_append<typename Msgs::fields_t ...>>;
711
+ combiner<Name, stdx::append_env_t <typename Msgs::env_t ...>>,
712
+ boost::mp11::mp_append<typename Msgs::fields_t ...>>;
693
713
};
694
714
} // namespace detail
695
715
@@ -709,32 +729,37 @@ using is_locatable = std::bool_constant<requires { F::sort_key; }>;
709
729
template <typename F1, typename F2>
710
730
using field_size_sort_fn = std::bool_constant < F2::bitsize<F1::bitsize>;
711
731
712
- template <stdx::ct_string Name, typename ... Fields> struct field_locator {
732
+ template <stdx::ct_string Name, typename ... Fields>
733
+ struct field_locator : field_locator<Name, stdx::env<>, Fields...> {};
734
+
735
+ template <stdx::ct_string Name, stdx::envlike Env, typename ... Fields>
736
+ struct field_locator <Name, Env, Fields...> {
713
737
using fields = boost::mp11::mp_partition<boost::mp11::mp_list<Fields...>,
714
738
is_locatable>;
715
739
using located_fields = boost::mp11::mp_first<fields>;
716
740
using unlocated_fields = boost::mp11::mp_second<fields>;
717
741
718
- using located_msg = boost::mp11::mp_apply_q<combiner<Name>, located_fields>;
742
+ using located_msg =
743
+ boost::mp11::mp_apply_q<combiner<Name, stdx::env<>>, located_fields>;
719
744
720
745
using auto_fields =
721
746
boost::mp11::mp_sort<unlocated_fields, field_size_sort_fn>;
722
747
723
748
template <typename F>
724
749
using as_singleton_message =
725
- msg::message<Name, typename F::default_located>;
750
+ msg::message<Name, Env, typename F::default_located>;
726
751
using auto_msgs =
727
752
boost::mp11::mp_transform<as_singleton_message, auto_fields>;
728
753
729
754
using all_msgs = boost::mp11::mp_push_front<auto_msgs, located_msg>;
730
755
731
756
template <typename ... Msgs>
732
757
using pack = msg::pack<Name, std::uint8_t , Msgs...>;
733
- using msg_type = boost::mp11::mp_apply<pack, all_msgs>;
758
+ using msg_type =
759
+ typename boost::mp11::mp_apply<pack, all_msgs>::template with_env<Env>;
734
760
};
735
761
} // namespace detail
736
762
737
- template <stdx::ct_string Name, typename ... Fields>
738
- using relaxed_message =
739
- typename detail::field_locator<Name, Fields...>::msg_type;
763
+ template <stdx::ct_string Name, typename ... Ts>
764
+ using relaxed_message = typename detail::field_locator<Name, Ts...>::msg_type;
740
765
} // namespace msg
0 commit comments