Skip to content

Commit 1e53630

Browse files
committed
Implement wrapping of class members
* Closes #10
1 parent 8521c65 commit 1e53630

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

include/function2/function2.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,22 @@ constexpr auto invoke(Type T::*member, Self&& self, Args&&... args) noexcept(
115115
(std::forward<Self>(self)->*member)(std::forward<Args>(args)...)) {
116116
return (std::forward<Self>(self)->*member)(std::forward<Args>(args)...);
117117
}
118+
/// Invokes the given pointer to a scalar member by reference
119+
template <typename T, typename Type, typename Self>
120+
constexpr auto
121+
invoke(Type T::*member,
122+
Self&& self) noexcept(noexcept(std::forward<Self>(self).*member))
123+
-> decltype(std::forward<Self>(self).*member) {
124+
return (std::forward<Self>(self).*member);
125+
}
126+
/// Invokes the given pointer to a scalar member by pointer
127+
template <typename T, typename Type, typename Self>
128+
constexpr auto
129+
invoke(Type T::*member,
130+
Self&& self) noexcept(noexcept(std::forward<Self>(self)->*member))
131+
-> decltype(std::forward<Self>(self)->*member) {
132+
return std::forward<Self>(self)->*member;
133+
}
118134

119135
/// Deduces to a true type if the callable object can be invoked with
120136
/// the given arguments.
@@ -140,6 +156,20 @@ struct can_invoke<Pointer, identity<T*, Args...>,
140156
decltype(
141157
(void)((std::declval<T*>()->*std::declval<Pointer>())(
142158
std::declval<Args>()...)))> : std::true_type {};
159+
template <typename Pointer, typename T>
160+
struct can_invoke<Pointer, identity<T&>,
161+
decltype((void)(std::declval<T&>().*std::declval<Pointer>()))>
162+
: std::true_type {};
163+
template <typename Pointer, typename T>
164+
struct can_invoke<Pointer, identity<T&&>,
165+
decltype((void)(std::declval<T&&>().*
166+
std::declval<Pointer>()))> : std::true_type {
167+
};
168+
template <typename Pointer, typename T>
169+
struct can_invoke<Pointer, identity<T*>,
170+
decltype(
171+
(void)(std::declval<T*>()->*std::declval<Pointer>()))>
172+
: std::true_type {};
143173
} // end namespace invocation
144174

145175
namespace overloading {

test/regressions.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,17 @@ TEST(regression_tests, reference_parameters_issue_7) {
3939
int i = 4384674;
4040
ASSERT_EQ(f(i), 4384674);
4141
}
42+
43+
struct scalar_member {
44+
explicit scalar_member(int num) : num_(num) {
45+
}
46+
int num_;
47+
};
48+
49+
/// https://github.com/Naios/function2/issues/10
50+
TEST(regression_tests, scalar_members_issue_10) {
51+
scalar_member const obj(4384674);
52+
53+
fu2::function<int(scalar_member const&)> fn = &scalar_member::num_;
54+
ASSERT_EQ(fn(obj), 4384674);
55+
}

0 commit comments

Comments
 (0)