Skip to content

Commit

Permalink
Refactor to add symmetry with member object
Browse files Browse the repository at this point in the history
  • Loading branch information
sdebionne committed Jun 11, 2019
1 parent 24c5a6e commit daa802d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 10 deletions.
14 changes: 9 additions & 5 deletions include/boost/hana/detail/struct_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace struct_detail {
template <typename Memptr, Memptr ptr>
struct member_ptr {
template <typename T, typename = std::enable_if_t<!std::is_member_function_pointer_v<Memptr>>>
constexpr decltype(auto) operator()(T&& t) const
template <typename Memptr2, typename T, std::enable_if_t<std::is_member_object_pointer_v<Memptr2>, int> = 0>
constexpr decltype(auto) dispatch(T && t) const
{ return static_cast<T&&>(t).*ptr; }

template <typename T, typename ... Args, typename = std::enable_if_t<std::is_member_function_pointer_v<Memptr>>>
constexpr decltype(auto) operator()(T&& t, Args&&... args) const
{ return (static_cast<T&&>(t).*ptr)(std::forward<Args>(args)...); }
template <typename Memptr2, typename T, std::enable_if_t<std::is_member_function_pointer_v<Memptr2>, int> = 0>
constexpr decltype(auto) dispatch(T && t) const
{ return [&](auto ... args) { return static_cast<T&&>(t).*ptr(args); }; }

template <typename T>
constexpr decltype(auto) operator()(T && t) const
{ return dispatch<Memptr>(t); }
};

constexpr std::size_t strlen(char const* s) {
Expand Down
14 changes: 9 additions & 5 deletions include/boost/hana/detail/struct_macros.hpp.erb
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,17 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace struct_detail {
template <typename Memptr, Memptr ptr>
struct member_ptr {
template <typename T, typename = std::enable_if_t<!std::is_member_function_pointer_v<Memptr>>>
constexpr decltype(auto) operator()(T&& t) const
template <typename Memptr2, typename T, std::enable_if_t<std::is_member_object_pointer_v<Memptr2>, int> = 0>
constexpr decltype(auto) dispatch(T && t) const
{ return static_cast<T&&>(t).*ptr; }

template <typename T, typename ... Args, typename = std::enable_if_t<std::is_member_function_pointer_v<Memptr>>>
constexpr decltype(auto) operator()(T&& t, Args&&... args) const
{ return (static_cast<T&&>(t).*ptr)(std::forward<Args>(args)...); }
template <typename Memptr2, typename T, std::enable_if_t<std::is_member_function_pointer_v<Memptr2>, int> = 0>
constexpr decltype(auto) dispatch(T && t) const
{ return [&](auto ... args) { return static_cast<T&&>(t).*ptr(args); }; }

template <typename T>
constexpr decltype(auto) operator()(T && t) const
{ return dispatch<Memptr>(t); }
};

constexpr std::size_t strlen(char const* s) {
Expand Down

0 comments on commit daa802d

Please sign in to comment.