@@ -664,25 +664,23 @@ namespace detail {
664
664
template <typename AlignTo, typename ... Msgs>
665
665
using msg_sizes = stdx::type_list<typename Msgs::template size<AlignTo>...>;
666
666
667
- template <typename S>
668
- using negated_size = std::integral_constant<std::size_t , -S::value>;
669
-
670
667
template <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 > >;
676
673
677
674
template <typename AlignTo> struct shift_msg_q {
678
675
template <typename Offset, typename Msg>
679
676
using fn = typename Msg::template shifted_by<Offset::value, AlignTo>;
680
677
};
681
678
682
679
template <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" >>>;
686
684
687
685
template <stdx::ct_string Name> struct combiner {
688
686
template <typename ... Fields> using fn = msg::message<Name, Fields...>;
@@ -704,4 +702,40 @@ template <stdx::ct_string Name, typename AlignTo, typename... Msgs>
704
702
requires (sizeof ...(Msgs) > 0 )
705
703
using pack = boost::mp11::mp_apply_q<detail::combine_q<Name>,
706
704
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;
707
741
} // namespace msg
0 commit comments