17 #ifndef MSG_DEF_H_INCLUDED
18 #define MSG_DEF_H_INCLUDED
21 #ifndef ALCHEMY_H_INCLUDED
22 # error Do not include this file directly. Use <alchemy.h> instead
32 #pragma warning(disable : 4503) // decorated name length exceeded, name was truncated
36 #include <Pb/meta_fwd.h>
37 #include <Pb/auto_index.h>
39 #include <Pb/length.h>
40 #include <Pb/offset_of.h>
41 #include <Pb/size_at.h>
42 #include <Pb/size_of.h>
43 #include <Pb/meta_math.h>
44 #include <Pb/dynamic.h>
45 #include <Hg/deduce_msg_type_list.h>
46 #include <Hg/make_Hg_type_list.h>
47 #include <Hg/proxy/deduce_proxy_type.h>
58 typedef size_t (*pfnGetDatumSize)(
const uint8_t*, size_t);
74 template<
typename T >
77 < has_dynamic<T>::value,
92 #define START_NAMESPACE(NS) namespace NS {
93 #define END_NAMESPACE(NS) }
97 #define DO_REMOVE(...) __VA_ARGS__
98 #define REMOVE_PARENS(N) DO_REMOVE N
100 #define BOOST_PP_REMOVE_PARENS(param) \
103 BOOST_PP_IS_BEGIN_PARENS(param), \
110 #define EACH_TYPE(r, data, i, x) \
111 REMOVE_PARENS(BOOST_PP_TUPLE_ELEM(3,0,x)),
113 #define EACH_PARAM(r, data, i, x) \
114 BOOST_PP_TUPLE_ELEM(3,1,x)(BOOST_PP_TUPLE_ELEM(3,2,x));
116 #define DEFINE_TYPELIST(N,...)\
117 typedef TypeList < __VA_ARGS__ > N;
119 #define DEFINE_PARAMLIST(...)\
123 #if defined(_MSC_VER)
124 #define DEFINE_STRUCT_TYPELIST(N, S) \
126 BOOST_PP_SEQ_FOR_EACH_I(EACH_TYPE, unused, BOOST_PP_VARIADIC_TO_SEQ(S)) Hg::MT)
129 #define DEFINE_STRUCT_PARAMS(S) \
130 BOOST_PP_SEQ_FOR_EACH_I(EACH_PARAM, unused, BOOST_PP_VARIADIC_TO_SEQ(S))
134 #define DEFINE_STRUCT_TYPELIST(N, ...) \
136 BOOST_PP_SEQ_FOR_EACH_I(EACH_TYPE, unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__)) Hg::MT)
139 #define DEFINE_STRUCT_PARAMS(...) \
140 BOOST_PP_SEQ_FOR_EACH_I(EACH_PARAM, unused, BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__))
152 #define DECLARE_STRUCT_HEADER(F, ...) \
153 START_NAMESPACE(Hg) \
154 DEFINE_STRUCT_TYPELIST(F##_tl, __VA_ARGS__) \
155 typedef Hg::make_Hg_type_list<F##_tl>::type F##_Hg; \
160 typedef F this_type; \
161 typedef F##_tl format_type; \
162 enum { k_size = SizeOf<format_type>::value }; \
163 enum { k_length = length<format_type>::value }; \
165 template< size_t IDX> \
166 Datum<IDX, format_type>& FieldAt() \
168 typedef Datum < IDX, \
169 format_type> datum_type_t; \
170 return this_type::FieldAtIndex((datum_type_t*)0); \
172 template< size_t IDX> \
173 const Datum<IDX, format_type>& const_FieldAt() const \
175 return const_cast<this_type*>(this)->FieldAt<IDX>(); \
179 DEFINE_STRUCT_PARAMS(__VA_ARGS__) \
180 DECLARE_STRUCT_FOOTER(F)
184 #define DECLARE_STRUCT_FOOTER(F) \
186 template <typename T, typename U> \
187 size_t DatumSize(T value, U*) \
192 template <typename U> \
193 size_t DatumSize(pfnGetDatumSize ftor, U* buffer) \
195 if (buffer->empty()) { return 0; } \
196 return ftor(buffer->data(), buffer->size()); \
199 START_NAMESPACE(detail) \
201 struct field_data_t <F##_Hg> \
203 typedef F value_type; \
205 END_NAMESPACE(detail) \
210 #define DECLARE_DATUM_ENTRY_IDX(IDX,P) \
212 Hg::detail::DeduceProxyType < IDX, \
213 format_type>::type Proxy##P; \
214 typedef Proxy##P::datum_type datum_##P; \
217 datum_##P& FieldAtIndex(const datum_##P*) \
218 { return *static_cast<datum_##P*>(&P); } \
220 const char* FieldName(const Proxy##P&) { return #P; }
223 #define DECLARE_DATUM_ENTRY_X(P) \
225 DECLARE_DATUM_ENTRY_IDX((COUNTER_VALUE), P)
228 #define D_FUNDAMENTAL(...) DECLARE_DATUM_ENTRY_X __VA_ARGS__
231 #define D_DATUM_X(T,P) (T,D_FUNDAMENTAL,(P))
232 #define D_DATUM(T,P) D_DATUM_X((T),P)
235 #define DECLARE_ARRAY(T,N) std::array<T,N>
238 #define DECLARE_VECTOR(T) std::vector<T>
241 #define DECLARE_ALLOCATED_VECTOR(T,A) std::vector<T,A>
244 #define D_ARRAY(T, N, P) D_DATUM_X((DECLARE_ARRAY(T,N)), P)
247 #define D_DYNAMIC(N,P) \
248 DECLARE_DATUM_ENTRY_X(P) \
250 template <typename U> \
251 size_t Size(U& buffer, datum_##P*) { return DatumSize(N, &buffer); }
254 #define D_DYNAMIC2(...) D_DYNAMIC __VA_ARGS__
255 #define D_VECTOR(T,N,P) ((DECLARE_VECTOR(T)),D_DYNAMIC2,(N,P))
258 #define DECLARE_ARRAY_ENTRY(T, N, P) D_ARRAY(T, N, P)
259 #define DECLARE_DYNAMIC_ENTRY(T, N, P) D_VECTOR(T, N, P)
260 #define DECLARE_ALLOCATOR_ENTRY(T, A, N, P) D_VECTOR(DECLARE_ALLOCATED_VECTOR(T,A), N, P)
267 #define DECLARE_PACKED_HEADER(T,C) \
268 START_NAMESPACE(Hg) \
271 struct ContainerSize<C> \
272 : std::integral_constant<size_t, sizeof(T)> { }; \
275 : public PackedBits<T> \
277 typedef C this_type; \
278 typedef T value_type; \
279 typedef PackedBits<T> base_type; \
285 C(const value_type &data_field) \
287 { value(data_field); } \
289 C(value_type &data_field) \
290 : base_type(data_field) \
293 C& operator=(const C &rhs) \
294 { value(rhs.value()); \
297 C& operator=(const value_type &data_field) \
298 { value(data_field); \
302 enum { k_offset_0 = 0 }; \
306 #define DECLARE_BIT_FIELD(IDX,P,N) \
307 typedef FieldIndex< IDX, this_type,N> idx_##IDX; \
309 { static ptrdiff_t offset() \
310 { return offsetof(this_type, P); } \
313 typedef BitField < this_type, P##_tag, k_offset_##IDX, N, value_type > P##_t; \
314 enum { TMP_PASTE(k_offset_, TMP_INC(IDX)) = k_offset_##IDX + N }; \
319 #define DECLARE_PACKED_FOOTER \
328 DECLARE_STRUCT_HEADER(NAME, __VA_ARGS__)
330 DECLARE_ARRAY_ENTRY(TYPE,COUNT,NAME)
331 DECLARE_DYNAMIC_ENTRY(TYPE,COUNT,NAME)
332 D_ALLOCATOR(TYPE,ALLOCATOR,COUNT,NAME)
333 DECLARE_STRUCT_FOOTER(TYPE_LIST)
335 DECLARE_PACKED_HEADER(TYPE,NAME)
336 DECLARE_BIT_FIELD(INDEX, NAME, COUNT)
337 DECLARE_PACKED_FOOTER
339 #endif // __cplusplus