diff --git a/example/bind_tools.cpp b/example/bind_tools.cpp new file mode 100644 index 0000000..eb5b09e --- /dev/null +++ b/example/bind_tools.cpp @@ -0,0 +1,65 @@ +/* + +Copyright Barrett Adair 2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +*/ + +#include +#include +#include +#include +#include + +struct Vampire {}; +struct Robot {}; +struct Animal {}; +struct Dog : Animal {}; +struct Poodle : Dog {}; +struct VampireRobotPoodle : Poodle, Robot, Vampire {}; + +auto take_vampire(const Vampire&) { return 0; } +auto take_robot(const Robot&) { return 0; } +auto take_dog(const Dog&) { return 0; } +auto take_vampire_robot_poodle(const VampireRobotPoodle&) { return 0; } + +int f(int, int, int, int) { return 0; } + +using namespace std::placeholders; +namespace ct = callable_traits; + +int main() { + + using bind_expr = decltype(ct::bind_expr( + &f, + ct::bind_expr(&take_vampire, _1), + ct::bind_expr(&take_robot, _1), + ct::bind_expr(&take_dog, _1), + ct::bind_expr(&take_vampire_robot_poodle, _1) + )); + + auto bind_obj = std::bind( + &f, + std::bind(&take_vampire, _1), + std::bind(&take_robot, _1), + std::bind(&take_dog, _1), + std::bind(&take_vampire_robot_poodle, _1) + ); + + using bind_args = ct::args; + using expected_args = std::tuple; + static_assert(std::is_same{}, ""); + + using bind_signature = ct::signature; + using expected_signature = int(const VampireRobotPoodle&); + static_assert(std::is_same{}, ""); + + VampireRobotPoodle vampire_robot_poodle; + assert(bind_obj(vampire_robot_poodle) == 0); + + std::function func = bind_obj; + assert(func(vampire_robot_poodle) == 0); + + return 0; +} \ No newline at end of file diff --git a/include/callable_traits/bind_expression_parser.hpp b/include/callable_traits/bind_expression_parser.hpp index 6e42fc7..e829b41 100644 --- a/include/callable_traits/bind_expression_parser.hpp +++ b/include/callable_traits/bind_expression_parser.hpp @@ -112,6 +112,14 @@ namespace callable_traits { using type = std::tuple<>; }; + template + struct build_function {}; + + template + struct build_function>{ + using type = Return(Args...); + }; + template struct bind_expression_parser; @@ -133,6 +141,8 @@ namespace callable_traits { >; using arg_types = typename common_expected_arg_types::type; + using return_type = typename root_expression::return_type; + using function_type = typename build_function::type; }; } } diff --git a/include/callable_traits/callable_traits.hpp b/include/callable_traits/callable_traits.hpp index 186c4a4..80c9282 100644 --- a/include/callable_traits/callable_traits.hpp +++ b/include/callable_traits/callable_traits.hpp @@ -51,6 +51,16 @@ namespace callable_traits { ctdetail::traits >::type::arg_types; + template< + typename T, + typename U = typename std::remove_cv::type>::type + > + using signature = typename std::conditional< + ctdetail::is_bind_expression::value, + ctdetail::bind_expression_parser, + ctdetail::traits + >::type::function_type; + template using arg_at = typename std::tuple_element>::type;