Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions include/chaiscript/dispatchkit/register_function.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,43 @@ namespace chaiscript {
return dispatch::detail::make_callable(std::forward<T>(t), dispatch::detail::function_signature(t));
}

/// \brief Creates a new Proxy_Function object from an overloaded free function, with the
/// signature specified explicitly to disambiguate the overload.
///
/// \b Example:
/// \code
/// int overloaded(int);
/// double overloaded(double);
///
/// chai.add(chaiscript::fun<int(int)>(&overloaded), "overloaded");
/// chai.add(chaiscript::fun<double(double)>(&overloaded), "overloaded");
/// \endcode
template<typename Sig, std::enable_if_t<std::is_function_v<Sig>, int> = 0>
Proxy_Function fun(std::type_identity_t<Sig> *f) {
return dispatch::detail::make_callable(f, dispatch::detail::function_signature(f));
}

/// \brief Creates a new Proxy_Function object from an overloaded member function, with the
/// signature specified explicitly to disambiguate the overload.
///
/// \b Example:
/// \code
/// class MyClass {
/// public:
/// int overloaded(int);
/// double overloaded(double);
/// int const_overloaded() const;
/// };
///
/// chai.add(chaiscript::fun<int(int)>(&MyClass::overloaded), "overloaded");
/// chai.add(chaiscript::fun<double(double)>(&MyClass::overloaded), "overloaded");
/// chai.add(chaiscript::fun<int() const>(&MyClass::const_overloaded), "const_overloaded");
/// \endcode
template<typename Sig, typename Class, std::enable_if_t<std::is_function_v<Sig>, int> = 0>
Proxy_Function fun(std::type_identity_t<Sig> Class::*f) {
return dispatch::detail::make_callable(f, dispatch::detail::function_signature(f));
}

/// \brief Creates a new Proxy_Function object from a free function, member function or data member and binds the first parameter of it
/// \param[in] t Function / member to expose
/// \param[in] q Value to bind to first parameter
Expand Down
68 changes: 68 additions & 0 deletions unittests/compiled_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,74 @@ TEST_CASE("Utility_Test utility class wrapper") {
chai.eval("t = Utility_Test();");
}

///// Issue 612: fun<Sig>(&overloaded) should work for free and member function overloads

namespace issue_612 {
std::string free_overload(int) { return "int"; }
std::string free_overload(double) { return "double"; }
std::string free_overload(const std::string &, bool) { return "string,bool"; }

class Issue_612_Class {
public:
std::string member_overload(int) { return "int"; }
std::string member_overload(double) { return "double"; }
std::string const_member_overload(int) const { return "const_int"; }
std::string const_member_overload(double) const { return "const_double"; }
};
} // namespace issue_612

TEST_CASE("Issue 612: fun<Signature> for overloaded free functions") {
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());

chai.add(chaiscript::fun<std::string(int)>(&issue_612::free_overload), "free_overload");
chai.add(chaiscript::fun<std::string(double)>(&issue_612::free_overload), "free_overload");
chai.add(chaiscript::fun<std::string(const std::string &, bool)>(&issue_612::free_overload), "free_overload");

CHECK(chai.eval<std::string>("free_overload(1)") == "int");
CHECK(chai.eval<std::string>("free_overload(1.5)") == "double");
CHECK(chai.eval<std::string>("free_overload(\"hi\", true)") == "string,bool");
}

TEST_CASE("Issue 612: fun<Signature> for overloaded member functions (pointer-to-member form)") {
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());

chai.add(chaiscript::user_type<issue_612::Issue_612_Class>(), "Issue_612_Class");
chai.add(chaiscript::constructor<issue_612::Issue_612_Class()>(), "Issue_612_Class");

chai.add(chaiscript::fun<std::string (issue_612::Issue_612_Class::*)(int)>(&issue_612::Issue_612_Class::member_overload),
"member_overload");
chai.add(chaiscript::fun<std::string (issue_612::Issue_612_Class::*)(double)>(&issue_612::Issue_612_Class::member_overload),
"member_overload");
chai.add(chaiscript::fun<std::string (issue_612::Issue_612_Class::*)(int) const>(&issue_612::Issue_612_Class::const_member_overload),
"const_member_overload");
chai.add(chaiscript::fun<std::string (issue_612::Issue_612_Class::*)(double) const>(&issue_612::Issue_612_Class::const_member_overload),
"const_member_overload");

chai.eval("var t = Issue_612_Class();");
CHECK(chai.eval<std::string>("t.member_overload(1)") == "int");
CHECK(chai.eval<std::string>("t.member_overload(1.5)") == "double");
CHECK(chai.eval<std::string>("t.const_member_overload(1)") == "const_int");
CHECK(chai.eval<std::string>("t.const_member_overload(1.5)") == "const_double");
}

TEST_CASE("Issue 612: fun<Signature> for overloaded member functions (function-type form)") {
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(), create_chaiscript_parser());

chai.add(chaiscript::user_type<issue_612::Issue_612_Class>(), "Issue_612_Class");
chai.add(chaiscript::constructor<issue_612::Issue_612_Class()>(), "Issue_612_Class");

chai.add(chaiscript::fun<std::string(int)>(&issue_612::Issue_612_Class::member_overload), "member_overload");
chai.add(chaiscript::fun<std::string(double)>(&issue_612::Issue_612_Class::member_overload), "member_overload");
chai.add(chaiscript::fun<std::string(int) const>(&issue_612::Issue_612_Class::const_member_overload), "const_member_overload");
chai.add(chaiscript::fun<std::string(double) const>(&issue_612::Issue_612_Class::const_member_overload), "const_member_overload");

chai.eval("var t = Issue_612_Class();");
CHECK(chai.eval<std::string>("t.member_overload(1)") == "int");
CHECK(chai.eval<std::string>("t.member_overload(1.5)") == "double");
CHECK(chai.eval<std::string>("t.const_member_overload(1)") == "const_int");
CHECK(chai.eval<std::string>("t.const_member_overload(1.5)") == "const_double");
}

enum Utility_Test_Numbers {
ONE,
TWO,
Expand Down
Loading