@@ -664,25 +664,23 @@ namespace detail {
664664template <typename AlignTo, typename ... Msgs>
665665using msg_sizes = stdx::type_list<typename Msgs::template size<AlignTo>...>;
666666
667- template <typename S>
668- using negated_size = std::integral_constant<std::size_t , -S::value>;
669-
670667template <typename AlignTo, typename ... Msgs>
671- using msg_offsets = boost::mp11::mp_partial_sum <
672- msg_sizes<AlignTo, Msgs...>,
673- negated_size< typename boost::mp11::mp_first<
674- stdx::type_list<Msgs...>>:: template size<AlignTo> >,
675- boost::mp11::mp_plus >;
668+ using msg_offsets = boost::mp11::mp_push_front <
669+ boost::mp11::mp_partial_sum< msg_sizes<AlignTo, Msgs...>,
670+ std::integral_constant<std:: size_t , 0 >,
671+ boost::mp11::mp_plus >,
672+ std::integral_constant<std:: size_t , 0 > >;
676673
677674template <typename AlignTo> struct shift_msg_q {
678675 template <typename Offset, typename Msg>
679676 using fn = typename Msg::template shifted_by<Offset::value, AlignTo>;
680677};
681678
682679template <typename AlignTo, typename ... Msgs>
683- using shifted_msgs = boost::mp11::mp_transform_q<shift_msg_q<AlignTo>,
684- msg_offsets<AlignTo, Msgs...>,
685- stdx::type_list<Msgs...>>;
680+ using shifted_msgs =
681+ boost::mp11::mp_transform_q<shift_msg_q<AlignTo>,
682+ msg_offsets<AlignTo, Msgs...>,
683+ stdx::type_list<Msgs..., msg::message<" end" >>>;
686684
687685template <stdx::ct_string Name> struct combiner {
688686 template <typename ... Fields> using fn = msg::message<Name, Fields...>;
@@ -704,4 +702,40 @@ template <stdx::ct_string Name, typename AlignTo, typename... Msgs>
704702 requires (sizeof ...(Msgs) > 0 )
705703using pack = boost::mp11::mp_apply_q<detail::combine_q<Name>,
706704 detail::shifted_msgs<AlignTo, Msgs...>>;
705+
706+ namespace detail {
707+ template <typename F>
708+ using is_locatable = std::bool_constant<requires { F::sort_key; }>;
709+
710+ template <typename F1, typename F2>
711+ using field_size_sort_fn = std::bool_constant < F2::bitsize<F1::bitsize>;
712+
713+ template <stdx::ct_string Name, typename ... Fields> struct field_locator {
714+ using fields = boost::mp11::mp_partition<boost::mp11::mp_list<Fields...>,
715+ is_locatable>;
716+ using located_fields = boost::mp11::mp_first<fields>;
717+ using unlocated_fields = boost::mp11::mp_second<fields>;
718+
719+ using located_msg = boost::mp11::mp_apply_q<combiner<Name>, located_fields>;
720+
721+ using auto_fields =
722+ boost::mp11::mp_sort<unlocated_fields, field_size_sort_fn>;
723+
724+ template <typename F>
725+ using as_singleton_message =
726+ msg::message<Name, typename F::default_located>;
727+ using auto_msgs =
728+ boost::mp11::mp_transform<as_singleton_message, auto_fields>;
729+
730+ using all_msgs = boost::mp11::mp_push_front<auto_msgs, located_msg>;
731+
732+ template <typename ... Msgs>
733+ using pack = msg::pack<Name, std::uint8_t , Msgs...>;
734+ using msg_type = boost::mp11::mp_apply<pack, all_msgs>;
735+ };
736+ } // namespace detail
737+
738+ template <stdx::ct_string Name, typename ... Fields>
739+ using relaxed_message =
740+ typename detail::field_locator<Name, Fields...>::msg_type;
707741} // namespace msg
0 commit comments