99
1010#include < stdx/compiler.hpp>
1111#include < stdx/ct_string.hpp>
12- #include < stdx/cx_vector .hpp>
12+ #include < stdx/env .hpp>
1313#include < stdx/iterator.hpp>
1414#include < stdx/ranges.hpp>
1515#include < stdx/span.hpp>
@@ -197,7 +197,7 @@ template <typename... Fields> struct storage_size {
197197
198198template <typename F> using name_for = typename F::name_t ;
199199
200- template <stdx::ct_string Name, typename ... Fields> class message_access {
200+ template <stdx::ct_string Name, typename ... Fields> class msg_access {
201201 using FieldsTuple =
202202 decltype (stdx::make_indexed_tuple<name_for>(Fields{}...));
203203
@@ -295,10 +295,11 @@ concept storage_like = stdx::range<T> and requires {
295295 typename T::value_type;
296296};
297297
298- template <stdx::ct_string Name, typename ... Fields> struct message ;
298+ template <stdx::ct_string Name, typename Env, typename ... Fields>
299+ struct message ;
299300
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...>;
302303};
303304
304305template <typename F1, typename F2>
@@ -312,9 +313,9 @@ using unique_by_name = boost::mp11::mp_unique_if<
312313 boost::mp11::mp_sort<boost::mp11::mp_list<Fields...>, field_sort_fn>,
313314 name_equal_fn>;
314315
315- template <stdx::ct_string Name, typename ... Fields>
316+ template <stdx::ct_string Name, typename Env, typename ... Fields>
316317using 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 >,
318319 detail::unique_by_name<Fields...>>;
319320
320321template <stdx::ct_string Name, typename ... Fields>
@@ -323,12 +324,45 @@ struct message_with_unique_field_names {
323324 name_for, boost::mp11::mp_list<Fields...>>>::value,
324325 " Message contains fields with duplicate names" );
325326
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...>;
327338};
328339
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 {
330363 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...>;
332366 using default_storage_t = typename access_t ::default_storage_t ;
333367 using default_span_t = typename access_t ::default_span_t ;
334368 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 {
342376
343377 template <auto N, typename Unit = bit_unit>
344378 using shifted_by =
345- message<Name, typename Fields::template shifted_by<N, Unit>...>;
379+ message<Name, Env, typename Fields::template shifted_by<N, Unit>...>;
346380
347381 template <typename S>
348382 constexpr static auto fits_inside =
349383 (... and Fields::template fits_inside<S>());
350384
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>;
371386
372387 template <typename > struct owner_t ;
373388
@@ -583,13 +598,17 @@ template <stdx::ct_string Name, typename... Fields> struct message {
583598 // name (see unique_by_name)
584599 template <stdx::ct_string NewName, typename ... NewFields>
585600 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...>;
587606};
588607} // namespace detail
589608
590- template <stdx::ct_string Name, typename ... Fields >
609+ template <stdx::ct_string Name, typename ... Ts >
591610using message =
592- typename detail::message_with_unique_field_names<Name, Fields ...>::type;
611+ typename detail::message_with_unique_field_names<Name, Ts ...>::type;
593612
594613template <typename T> using owning = typename T::template owner_t <>;
595614template <typename T> using mutable_view = typename T::mutable_view_t ;
@@ -681,15 +700,16 @@ using shifted_msgs =
681700 msg_offsets<AlignTo, Msgs...>,
682701 stdx::type_list<Msgs..., msg::message<" end" >>>;
683702
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...>;
686705};
687706
688707template <stdx::ct_string Name> struct combine_q {
689708 template <typename ... Msgs>
690709 requires (sizeof ...(Msgs) > 0 )
691710 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 ...>>;
693713};
694714} // namespace detail
695715
@@ -709,32 +729,37 @@ using is_locatable = std::bool_constant<requires { F::sort_key; }>;
709729template <typename F1, typename F2>
710730using field_size_sort_fn = std::bool_constant < F2::bitsize<F1::bitsize>;
711731
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...> {
713737 using fields = boost::mp11::mp_partition<boost::mp11::mp_list<Fields...>,
714738 is_locatable>;
715739 using located_fields = boost::mp11::mp_first<fields>;
716740 using unlocated_fields = boost::mp11::mp_second<fields>;
717741
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>;
719744
720745 using auto_fields =
721746 boost::mp11::mp_sort<unlocated_fields, field_size_sort_fn>;
722747
723748 template <typename F>
724749 using as_singleton_message =
725- msg::message<Name, typename F::default_located>;
750+ msg::message<Name, Env, typename F::default_located>;
726751 using auto_msgs =
727752 boost::mp11::mp_transform<as_singleton_message, auto_fields>;
728753
729754 using all_msgs = boost::mp11::mp_push_front<auto_msgs, located_msg>;
730755
731756 template <typename ... Msgs>
732757 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>;
734760};
735761} // namespace detail
736762
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;
740765} // namespace msg
0 commit comments