Skip to content

Commit

Permalink
use perfect forwarding with the visitor also
Browse files Browse the repository at this point in the history
  • Loading branch information
cbeck88 committed Jun 25, 2016
1 parent 3ea455a commit fb51bcb
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 10 deletions.
4 changes: 2 additions & 2 deletions include/visit_struct/visit_struct.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ VISIT_STRUCT_CONSTEXPR auto apply_visitor(V && v, S && s) ->
*/

#define VISIT_STRUCT_MEMBER_HELPER(MEMBER_NAME) \
visitor(#MEMBER_NAME, struct_instance.MEMBER_NAME);
std::forward<V>(visitor)(#MEMBER_NAME, struct_instance.MEMBER_NAME);

#define VISIT_STRUCT_MEMBER_HELPER_MOVE(MEMBER_NAME) \
visitor(#MEMBER_NAME, std::move(struct_instance.MEMBER_NAME));
std::forward<V>(visitor)(#MEMBER_NAME, std::move(struct_instance.MEMBER_NAME));


// This macro specializes the trait, provides "apply" method which does the work.
Expand Down
14 changes: 7 additions & 7 deletions include/visit_struct/visit_struct_boost_fusion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ struct visitable<S,
V visitor;
T struct_instance;

explicit helper(V v, T t) : visitor(v), struct_instance(t) {}
explicit helper(V v, T t) : visitor(std::forward<V>(v)), struct_instance(t) {}

template <typename Index>
void operator()(Index) const {
visitor(boost::fusion::extension::struct_member_name<S, Index::value>::call(), boost::fusion::at<Index>(struct_instance));
std::forward<V>(visitor)(boost::fusion::extension::struct_member_name<S, Index::value>::call(), boost::fusion::at<Index>(struct_instance));
}
};

Expand All @@ -50,33 +50,33 @@ struct visitable<S,
V visitor;
T struct_instance;

explicit helper_rvalue_ref(V v, T t) : visitor(v), struct_instance(std::move(t)) {}
explicit helper_rvalue_ref(V v, T t) : visitor(std::forward<V>(v)), struct_instance(std::move(t)) {}

template <typename Index>
void operator()(Index) const {
visitor(boost::fusion::extension::struct_member_name<S, Index::value>::call(), std::move(boost::fusion::at<Index>(struct_instance)));
std::forward<V>(visitor)(boost::fusion::extension::struct_member_name<S, Index::value>::call(), std::move(boost::fusion::at<Index>(struct_instance)));
}
};

public:
template <typename V>
static void apply(V && v, const S & s) {
typedef boost::mpl::range_c<unsigned, 0, boost::fusion::result_of::size<S>::value > Indices;
helper<V, const S &> h{v, s};
helper<decltype(std::forward<V>(v)), const S &> h{std::forward<V>(v), s};
boost::fusion::for_each(Indices(), h);
}

template <typename V>
static void apply(V && v, S & s) {
typedef boost::mpl::range_c<unsigned, 0, boost::fusion::result_of::size<S>::value > Indices;
helper<V, S &> h{v, s};
helper<decltype(std::forward<V>(v)), S &> h{std::forward<V>(v), s};
boost::fusion::for_each(Indices(), h);
}

template <typename V>
static void apply(V && v, S && s) {
typedef boost::mpl::range_c<unsigned, 0, boost::fusion::result_of::size<S>::value > Indices;
helper_rvalue_ref<V, S &&> h{v, std::move(s)};
helper_rvalue_ref<decltype(std::forward<V>(v)), S &&> h{std::forward<V>(v), std::move(s)};
boost::fusion::for_each(Indices(), h);
}

Expand Down
2 changes: 1 addition & 1 deletion include/visit_struct/visit_struct_intrusive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ template <typename M>
struct member_helper {
template <typename V, typename S>
VISIT_STRUCT_CONSTEXPR static void apply_visitor(V && visitor, S && structure_instance) {
visitor(M::member_name, M::apply(std::forward<S>(structure_instance)));
std::forward<V>(visitor)(M::member_name, M::apply(std::forward<S>(structure_instance)));
}
};

Expand Down
5 changes: 5 additions & 0 deletions test_visit_struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ struct test_visitor_three {
void operator()(const char *, int &&) {
result = 3;
}

// Make it non-copyable and non-moveable, apply visitor should still work.
test_visitor_three() = default;
test_visitor_three(const test_visitor_three &) = delete;
test_visitor_three(test_visitor_three &&) = delete;
};


Expand Down
5 changes: 5 additions & 0 deletions test_visit_struct_boost_fusion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ struct test_visitor_three {
void operator()(const char *, int &&) {
result = 3;
}

// Make it non-copyable and non-moveable, apply visitor should still work.
test_visitor_three() = default;
test_visitor_three(const test_visitor_three &) = delete;
test_visitor_three(test_visitor_three &&) = delete;
};


Expand Down
5 changes: 5 additions & 0 deletions test_visit_struct_intrusive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ struct test_visitor_three {
void operator()(const char *, int &&) {
result = 3;
}

// Make it non-copyable and non-moveable, apply visitor should still work.
test_visitor_three() = default;
test_visitor_three(const test_visitor_three &) = delete;
test_visitor_three(test_visitor_three &&) = delete;
};

// debug_print
Expand Down

0 comments on commit fb51bcb

Please sign in to comment.