6 #ifndef VISIT_STRUCT_INTRUSIVE_HPP_INCLUDED
7 #define VISIT_STRUCT_INTRUSIVE_HPP_INCLUDED
32 #include "visit_struct.h"
34 namespace visit_struct {
42 template <
class... Ts>
44 static VISIT_STRUCT_CONSTEXPR
const unsigned int size =
sizeof...(Ts);
48 template <
class List,
class T>
51 template <
class... Ts,
class T>
52 struct Append<TypeList<Ts...>, T> {
53 typedef TypeList<Ts..., T> type;
56 template<
class L,
class T>
57 using Append_t =
typename Append<L, T>::type;
63 template <
typename T,
typename... Ts>
64 struct Cdr<TypeList<T, Ts...>> {
65 typedef TypeList<Ts...> type;
69 using Cdr_t =
typename Cdr<List>::type;
72 template <
class List,
unsigned idx>
73 struct Find : Find<Cdr_t<List>, idx - 1> {};
75 template <
typename T,
typename... Ts>
76 struct Find<TypeList<T, Ts...>, 0> {
80 template <
class List,
unsigned idx>
81 using Find_t =
typename Find<List, idx>::type;
86 using char_array =
const char [N];
100 static VISIT_STRUCT_CONSTEXPR
const int max_visitable_members_intrusive = 100;
167 template <
typename S,
typename T, T S::*member_ptr>
169 static VISIT_STRUCT_CONSTEXPR T S::* get_ptr() {
return member_ptr; }
170 using value_type = T;
176 template <
typename M>
177 struct member_helper {
178 template <
typename V,
typename S>
179 VISIT_STRUCT_CXX14_CONSTEXPR
static void apply_visitor(V && visitor, S && structure_instance) {
180 std::forward<V>(visitor)(M::member_name(), std::forward<S>(structure_instance).*M::get_ptr());
183 template <
typename V,
typename S1,
typename S2>
184 VISIT_STRUCT_CXX14_CONSTEXPR
static void apply_visitor(V && visitor, S1 && s1, S2 && s2) {
185 std::forward<V>(visitor)(M::member_name(),
186 std::forward<S1>(s1).*M::get_ptr(),
187 std::forward<S2>(s2).*M::get_ptr());
190 template <
typename V>
191 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_pointers(V && visitor) {
192 std::forward<V>(visitor)(M::member_name(), M::get_ptr());
195 template <
typename V>
196 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_accessors(V && visitor) {
197 std::forward<V>(visitor)(M::member_name(),
typename M::accessor_t());
200 template <
typename V>
201 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_types(V && visitor) {
207 template <
typename Mlist>
208 struct structure_helper;
210 template <
typename... Ms>
212 template <
typename V,
typename S>
213 VISIT_STRUCT_CXX14_CONSTEXPR
static void apply_visitor(V && visitor, S && structure_instance) {
220 static_cast<void>(dummy);
221 static_cast<void>(visitor);
222 static_cast<void>(structure_instance);
225 template <
typename V,
typename S1,
typename S2>
226 VISIT_STRUCT_CXX14_CONSTEXPR
static void apply_visitor(V && visitor, S1 && s1, S2 && s2) {
228 static_cast<void>(dummy);
229 static_cast<void>(visitor);
230 static_cast<void>(s1);
231 static_cast<void>(s2);
234 template <
typename V>
235 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_pointers(V && visitor) {
236 int dummy[] = {(member_helper<Ms>::visit_pointers(std::forward<V>(visitor)), 0)..., 0};
237 static_cast<void>(dummy);
238 static_cast<void>(visitor);
241 template <
typename V>
242 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_accessors(V && visitor) {
243 int dummy[] = {(member_helper<Ms>::visit_accessors(std::forward<V>(visitor)), 0)..., 0};
244 static_cast<void>(dummy);
245 static_cast<void>(visitor);
248 template <
typename V>
249 VISIT_STRUCT_CXX14_CONSTEXPR
static void visit_types(V && visitor) {
251 static_cast<void>(dummy);
252 static_cast<void>(visitor);
266 template <
typename T>
268 typename std::enable_if<
269 std::is_same<typename T::Visit_Struct_Visitable_Structure_Tag__,
270 ::visit_struct::detail::intrusive_tag
275 static VISIT_STRUCT_CONSTEXPR
const std::size_t field_count = T::Visit_Struct_Registered_Members_List__::size;
279 template <
typename V,
typename S>
280 static VISIT_STRUCT_CXX14_CONSTEXPR
void apply(V && v, S && s) {
281 detail::structure_helper<typename T::Visit_Struct_Registered_Members_List__>::apply_visitor(std::forward<V>(v), std::forward<S>(s));
285 template <
typename V,
typename S1,
typename S2>
286 static VISIT_STRUCT_CXX14_CONSTEXPR
void apply(V && v, S1 && s1, S2 && s2) {
287 detail::structure_helper<typename T::Visit_Struct_Registered_Members_List__>::apply_visitor(std::forward<V>(v), std::forward<S1>(s1), std::forward<S2>(s2));
291 template <
typename V>
292 static VISIT_STRUCT_CXX14_CONSTEXPR
void visit_pointers(V && v) {
296 template <
typename V>
297 static VISIT_STRUCT_CXX14_CONSTEXPR
void visit_types(V && v) {
301 template <
typename V>
302 static VISIT_STRUCT_CXX14_CONSTEXPR
void visit_accessors(V && v) {
308 static VISIT_STRUCT_CONSTEXPR
auto get_pointer(std::integral_constant<int, idx>)
309 -> decltype(detail::Find_t<typename T::Visit_Struct_Registered_Members_List__, idx>::get_ptr())
311 return detail::Find_t<typename T::Visit_Struct_Registered_Members_List__, idx>::get_ptr();
316 static VISIT_STRUCT_CONSTEXPR
auto get_accessor(std::integral_constant<int, idx>)
317 ->
typename detail::Find_t<typename T::Visit_Struct_Registered_Members_List__, idx>::accessor_t
323 template <
int idx,
typename S>
324 static VISIT_STRUCT_CONSTEXPR
auto get_value(std::integral_constant<int, idx> tag, S && s)
325 -> decltype(std::forward<S>(s).*get_pointer(tag))
327 return std::forward<S>(s).*get_pointer(tag);
332 static VISIT_STRUCT_CONSTEXPR
auto get_name(std::integral_constant<int, idx>)
333 -> decltype(detail::Find_t<typename T::Visit_Struct_Registered_Members_List__, idx>::member_name())
335 return detail::Find_t<typename T::Visit_Struct_Registered_Members_List__, idx>::member_name();
340 static auto type_at(std::integral_constant<int, idx>)
344 static VISIT_STRUCT_CONSTEXPR decltype(T::Visit_Struct_Get_Name__()) get_name() {
345 return T::Visit_Struct_Get_Name__();
348 static VISIT_STRUCT_CONSTEXPR
const bool value =
true;
357 #define VISIT_STRUCT_GET_REGISTERED_MEMBERS decltype(Visit_Struct_Get_Visitables__(::visit_struct::detail::Rank<visit_struct::detail::max_visitable_members_intrusive>{}))
359 #define VISIT_STRUCT_MAKE_MEMBER_NAME(NAME) Visit_Struct_Member_Record__##NAME
361 #define BEGIN_VISITABLES(NAME) \
362 typedef NAME VISIT_STRUCT_CURRENT_TYPE; \
363 static VISIT_STRUCT_CONSTEXPR decltype(#NAME) Visit_Struct_Get_Name__() { \
366 ::visit_struct::detail::TypeList<> static inline Visit_Struct_Get_Visitables__(::visit_struct::detail::Rank<0>); \
367 static_assert(true, "")
369 #define VISITABLE(TYPE, NAME) \
371 struct VISIT_STRUCT_MAKE_MEMBER_NAME(NAME) : \
372 visit_struct::detail::member_ptr_helper<VISIT_STRUCT_CURRENT_TYPE, \
374 &VISIT_STRUCT_CURRENT_TYPE::NAME> \
376 static VISIT_STRUCT_CONSTEXPR const ::visit_struct::detail::char_array<sizeof(#NAME)> & member_name() { \
380 static inline ::visit_struct::detail::Append_t<VISIT_STRUCT_GET_REGISTERED_MEMBERS, \
381 VISIT_STRUCT_MAKE_MEMBER_NAME(NAME)> \
382 Visit_Struct_Get_Visitables__(::visit_struct::detail::Rank<VISIT_STRUCT_GET_REGISTERED_MEMBERS::size + 1>); \
383 static_assert(true, "")
385 #define END_VISITABLES \
386 typedef VISIT_STRUCT_GET_REGISTERED_MEMBERS Visit_Struct_Registered_Members_List__; \
387 typedef ::visit_struct::detail::intrusive_tag Visit_Struct_Visitable_Structure_Tag__; \
388 static_assert(true, "")
391 #endif // VISIT_STRUCT_INTRUSIVE_HPP_INCLUDED