/* 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) */ //useless MSVC /Wall warnings #pragma warning(disable: 4514 4711) #include #include #include #include #include struct Vampire {}; struct Robot {}; struct Animal {}; struct Dog : Animal {}; struct Poodle : Dog {}; struct VampireRobotPoodle : Vampire, Robot, Poodle {}; auto vampire_to_robot(Vampire) { return Robot{}; } auto robot_to_dog = [](Robot){ return Dog{}; }; struct converter { auto dog_to_vampire(Dog) { return Vampire{}; } }; int take_all(Vampire, Robot, Animal, Dog, Poodle, VampireRobotPoodle) { return 0; } using namespace std::placeholders; namespace ct = callable_traits; int main() { using bind_expr = decltype( ct::bind_expr(&take_all, ct::bind_expr(&converter::dog_to_vampire, converter{}, ct::bind_expr(robot_to_dog, ct::bind_expr(&vampire_to_robot, _1) ) ), ct::bind_expr(&vampire_to_robot, _3), Animal{}, _1, _2, _1 ) ); auto bind_obj = std::bind(&take_all, std::bind(&converter::dog_to_vampire, converter{}, std::bind(robot_to_dog, std::bind(&vampire_to_robot, _1) ) ), std::bind(&vampire_to_robot, _3), Animal{}, _1, _2, _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(VampireRobotPoodle, Poodle, Vampire); static_assert(std::is_same{}, ""); assert(bind_obj(VampireRobotPoodle{}, Poodle{}, Vampire{}) == 0); auto fn = std::function{ bind_obj }; assert(fn(VampireRobotPoodle{}, Poodle{}, Vampire{}) == 0); return 0; }