|
|
|
|
|
|
|
|
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) \ |