1
1
#pragma once
2
2
3
+ #include < log/catalog/arguments.hpp>
3
4
#include < log/catalog/catalog.hpp>
4
5
#include < log/catalog/mipi_messages.hpp>
5
6
7
+ #include < stdx/bit.hpp>
6
8
#include < stdx/compiler.hpp>
7
9
#include < stdx/type_traits.hpp>
8
10
#include < stdx/utility.hpp>
16
18
17
19
namespace logging ::mipi {
18
20
template <typename T>
19
- concept signed_packable = std::signed_integral<stdx:: underlying_type_t <T >> and
20
- sizeof (T) <= sizeof (std:: int64_t ) ;
21
+ concept packer = std::integral< typename T:: template pack_as_t < int >> and
22
+ requires { typename T:: template encode_as_t < int >; } ;
21
23
22
- template <typename T>
23
- concept unsigned_packable =
24
- std::unsigned_integral<stdx::underlying_type_t <T>> and
25
- sizeof (T) <= sizeof (std::int64_t );
26
-
27
- template <typename T>
28
- concept packable = signed_packable<T> or unsigned_packable<T>;
29
-
30
- template <typename T> struct encoding ;
31
-
32
- template <signed_packable T> struct encoding <T> {
33
- using encode_t = stdx::conditional_t <sizeof (T) <= sizeof (std::int32_t ),
34
- encode_32<T>, encode_64<T>>;
35
- using pack_t = stdx::conditional_t <sizeof (T) <= sizeof (std::int32_t ),
36
- std::int32_t , std::int64_t >;
37
- };
24
+ template <typename , packer> struct builder ;
38
25
39
- template <unsigned_packable T> struct encoding <T> {
40
- using encode_t = stdx::conditional_t <sizeof (T) <= sizeof (std::int32_t ),
41
- encode_u32<T>, encode_u64<T>>;
42
- using pack_t = stdx::conditional_t <sizeof (T) <= sizeof (std::uint32_t ),
43
- std::uint32_t , std::uint64_t >;
44
- };
45
-
46
- template <packable T> using pack_as_t = typename encoding<T>::pack_t ;
47
- template <packable T> using encode_as_t = typename encoding<T>::encode_t ;
48
-
49
- template <typename > struct builder ;
50
-
51
- template <> struct builder <defn::short32_msg_t > {
26
+ template <packer P> struct builder <defn::short32_msg_t , P> {
52
27
template <auto Level> static auto build (string_id id, module_id) {
53
28
using namespace msg ;
54
29
return owning<defn::short32_msg_t >{" payload" _field = id};
55
30
}
56
31
};
57
32
58
- template <typename Storage> struct catalog_builder {
33
+ template <typename Storage, packer P > struct catalog_builder {
59
34
template <auto Level, packable... Ts>
60
35
static auto build (string_id id, module_id m, Ts... args) {
61
36
using namespace msg ;
@@ -66,8 +41,16 @@ template <typename Storage> struct catalog_builder {
66
41
constexpr auto header_size = defn::catalog_msg_t ::size<V>::value;
67
42
68
43
auto const pack_arg = []<typename T>(V *p, T arg) -> V * {
69
- auto const packed = stdx::to_le (stdx::as_unsigned (
70
- static_cast <pack_as_t <T>>(stdx::to_underlying (arg))));
44
+ typename P::template pack_as_t <T> converted{};
45
+ if constexpr (sizeof (stdx::to_underlying (arg)) ==
46
+ sizeof (converted)) {
47
+ converted = stdx::bit_cast<decltype (converted)>(
48
+ stdx::to_underlying (arg));
49
+ } else {
50
+ converted =
51
+ static_cast <decltype (converted)>(stdx::to_underlying (arg));
52
+ }
53
+ auto const packed = stdx::to_le (stdx::as_unsigned (converted));
71
54
std::memcpy (p, &packed, sizeof (packed));
72
55
return p + stdx::sized8{sizeof (packed)}.in <V>();
73
56
};
@@ -80,48 +63,49 @@ template <typename Storage> struct catalog_builder {
80
63
}
81
64
};
82
65
83
- template <> struct builder <defn::catalog_msg_t > {
66
+ template <packer P > struct builder <defn::catalog_msg_t , P > {
84
67
template <auto Level, typename ... Ts>
85
68
static auto build (string_id id, module_id m, Ts... args) {
86
69
using namespace msg ;
87
70
if constexpr ((0 + ... + sizeof (Ts)) <= sizeof (std::uint32_t ) * 2 ) {
88
71
constexpr auto header_size =
89
72
defn::catalog_msg_t ::size<std::uint32_t >::value;
90
73
constexpr auto payload_size =
91
- stdx::sized8{(sizeof (id) + ... + sizeof (pack_as_t <Ts>))}
74
+ stdx::sized8{(sizeof (id) + ... +
75
+ sizeof (typename P::template pack_as_t <Ts>))}
92
76
.in <std::uint32_t >();
93
77
using storage_t =
94
78
std::array<std::uint32_t , header_size + payload_size>;
95
- return catalog_builder<storage_t >{}.template build <Level>(id, m,
96
- args...);
79
+ return catalog_builder<storage_t , P >{}.template build <Level>(
80
+ id, m, args...);
97
81
} else {
98
82
constexpr auto header_size =
99
83
defn::catalog_msg_t ::size<std::uint8_t >::value;
100
84
constexpr auto payload_size =
101
- (sizeof (id) + ... + sizeof (pack_as_t <Ts>));
85
+ (sizeof (id) + ... + sizeof (typename P:: template pack_as_t <Ts>));
102
86
using storage_t =
103
87
std::array<std::uint8_t , header_size + payload_size>;
104
- return catalog_builder<storage_t >{}.template build <Level>(id, m,
105
- args...);
88
+ return catalog_builder<storage_t , P >{}.template build <Level>(
89
+ id, m, args...);
106
90
}
107
91
}
108
92
};
109
93
110
- template <> struct builder <defn::compact32_build_msg_t > {
94
+ template <packer P > struct builder <defn::compact32_build_msg_t , P > {
111
95
template <auto Version> static auto build () {
112
96
using namespace msg ;
113
97
return owning<defn::compact32_build_msg_t >{" build_id" _field = Version};
114
98
}
115
99
};
116
100
117
- template <> struct builder <defn::compact64_build_msg_t > {
101
+ template <packer P > struct builder <defn::compact64_build_msg_t , P > {
118
102
template <auto Version> static auto build () {
119
103
using namespace msg ;
120
104
return owning<defn::compact64_build_msg_t >{" build_id" _field = Version};
121
105
}
122
106
};
123
107
124
- template <> struct builder <defn::normal_build_msg_t > {
108
+ template <packer P > struct builder <defn::normal_build_msg_t , P > {
125
109
template <auto Version, stdx::ct_string S> static auto build () {
126
110
using namespace msg ;
127
111
constexpr auto header_size =
@@ -141,32 +125,33 @@ template <> struct builder<defn::normal_build_msg_t> {
141
125
}
142
126
};
143
127
144
- struct default_builder {
128
+ template <packer P = logging::default_arg_packer> struct default_builder {
145
129
template <auto Level, packable... Ts>
146
130
static auto build (string_id id, module_id m, Ts... args) {
147
131
if constexpr (sizeof ...(Ts) == 0u ) {
148
- return builder<defn::short32_msg_t >{}.template build <Level>(id, m);
132
+ return builder<defn::short32_msg_t , P>{}.template build <Level>(id,
133
+ m);
149
134
} else {
150
- return builder<defn::catalog_msg_t >{}.template build <Level>(
135
+ return builder<defn::catalog_msg_t , P >{}.template build <Level>(
151
136
id, m, args...);
152
137
}
153
138
}
154
139
155
140
template <auto Version, stdx::ct_string S = " " > auto build_version () {
156
141
using namespace msg ;
157
142
if constexpr (S.empty () and stdx::bit_width (Version) <= 22 ) {
158
- return builder<defn::compact32_build_msg_t >{}
143
+ return builder<defn::compact32_build_msg_t , P >{}
159
144
.template build <Version>();
160
145
} else if constexpr (S.empty () and stdx::bit_width (Version) <= 54 ) {
161
- return builder<defn::compact64_build_msg_t >{}
146
+ return builder<defn::compact64_build_msg_t , P >{}
162
147
.template build <Version>();
163
148
} else {
164
- return builder<defn::normal_build_msg_t >{}
149
+ return builder<defn::normal_build_msg_t , P >{}
165
150
.template build <Version, S>();
166
151
}
167
152
}
168
153
169
154
template <template <typename ...> typename F, typename ... Args>
170
- using convert_args = F<encode_as_t <Args>...>;
155
+ using convert_args = F<typename P:: template encode_as_t <Args>...>;
171
156
};
172
157
} // namespace logging::mipi
0 commit comments