| return ::trompeloeil::neg_matcher<std::decay_t<M>>{std::forward<M>(m)}; | return ::trompeloeil::neg_matcher<std::decay_t<M>>{std::forward<M>(m)}; | ||||
| } | } | ||||
| /* | |||||
| * Convert the signature S of a mock function to the signature of | |||||
| * a member function of class T that takes the same parameters P | |||||
| * but returns R. | |||||
| * | |||||
| * The member function has the same constness as the mock function. | |||||
| */ | |||||
| template <typename T, typename R, typename S> | |||||
| struct signature_to_member_function; | |||||
| template <typename T, typename R, typename R_of_S, typename... P> | |||||
| struct signature_to_member_function<T, R, R_of_S(P...)> | |||||
| { | |||||
| using type = std::conditional_t< | |||||
| std::is_const<T>::value, | |||||
| R (T::*)(P...) const, | |||||
| R (T::*)(P...)>; | |||||
| }; | |||||
| } | } | ||||
| #define TROMPELOEIL_LINE_ID(name) \ | #define TROMPELOEIL_LINE_ID(name) \ | ||||
| "Function signature does not have " #num " parameters"); \ | "Function signature does not have " #num " parameters"); \ | ||||
| using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\ | using TROMPELOEIL_LINE_ID(matcher_list_t) = ::trompeloeil::call_matcher_list<sig>;\ | ||||
| using TROMPELOEIL_LINE_ID(expectation_list_t) = ::trompeloeil::expectations<sig>; \ | using TROMPELOEIL_LINE_ID(expectation_list_t) = ::trompeloeil::expectations<sig>; \ | ||||
| mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations);\ | |||||
| struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \ | struct TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \ | ||||
| { \ | { \ | ||||
| const char* trompeloeil_expectation_file; \ | const char* trompeloeil_expectation_file; \ | ||||
| { \ | { \ | ||||
| return TROMPELOEIL_LINE_ID(expectations).active; \ | return TROMPELOEIL_LINE_ID(expectations).active; \ | ||||
| } \ | } \ | ||||
| \ | |||||
| ::trompeloeil::return_of_t<sig> \ | ::trompeloeil::return_of_t<sig> \ | ||||
| name( \ | name( \ | ||||
| TROMPELOEIL_PARAM_LIST(num, sig)) \ | TROMPELOEIL_PARAM_LIST(num, sig)) \ | ||||
| constness \ | constness \ | ||||
| spec \ | spec \ | ||||
| { \ | { \ | ||||
| /* Use the auxiliary functions to avoid unneeded-member-function warning */\ | |||||
| using T_ ## name = typename std::remove_reference<decltype(*this)>::type; \ | |||||
| \ | |||||
| using pmf_s_t = typename ::trompeloeil::signature_to_member_function< \ | |||||
| T_ ## name, decltype(*this), sig>::type; \ | |||||
| \ | |||||
| using pmf_e_t = typename ::trompeloeil::signature_to_member_function< \ | |||||
| T_ ## name, TROMPELOEIL_LINE_ID(tag_type_trompeloeil), sig>::type; \ | |||||
| \ | |||||
| auto s_ptr = static_cast<pmf_s_t>(&T_ ## name::trompeloeil_self_ ## name); \ | |||||
| auto e_ptr = static_cast<pmf_e_t>(&T_ ## name::trompeloeil_tag_ ## name); \ | |||||
| \ | |||||
| ::trompeloeil::ignore(s_ptr, e_ptr); \ | |||||
| \ | |||||
| return ::trompeloeil::mock_func<sig>(TROMPELOEIL_LINE_ID(cardinality_match){}, \ | return ::trompeloeil::mock_func<sig>(TROMPELOEIL_LINE_ID(cardinality_match){}, \ | ||||
| TROMPELOEIL_LINE_ID(expectations), \ | TROMPELOEIL_LINE_ID(expectations), \ | ||||
| #name, \ | #name, \ | ||||
| \ | \ | ||||
| auto \ | auto \ | ||||
| trompeloeil_self_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \ | trompeloeil_self_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \ | ||||
| -> decltype(*this); \ | |||||
| -> decltype(*this) \ | |||||
| { \ | |||||
| ::trompeloeil::ignore(#name TROMPELOEIL_PARAMS(num)); \ | |||||
| return *this; \ | |||||
| } \ | |||||
| \ | \ | ||||
| TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \ | TROMPELOEIL_LINE_ID(tag_type_trompeloeil) \ | ||||
| trompeloeil_tag_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness | |||||
| trompeloeil_tag_ ## name(TROMPELOEIL_PARAM_LIST(num, sig)) constness \ | |||||
| { \ | |||||
| ::trompeloeil::ignore(#name TROMPELOEIL_PARAMS(num)); \ | |||||
| return {nullptr, 0ul, nullptr}; \ | |||||
| } \ | |||||
| \ | |||||
| mutable TROMPELOEIL_LINE_ID(expectation_list_t) TROMPELOEIL_LINE_ID(expectations) | |||||
| #define TROMPELOEIL_REQUIRE_CALL(obj, func) \ | #define TROMPELOEIL_REQUIRE_CALL(obj, func) \ |