Skip to content

Commit

Permalink
Test commit of new method id system to see if it works on other compi…
Browse files Browse the repository at this point in the history
…lers.
  • Loading branch information
FranckRJ committed May 12, 2024
1 parent d8612dc commit fe86008
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 78 deletions.
32 changes: 16 additions & 16 deletions include/fakeit/Mock.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,67 +71,67 @@ namespace fakeit {
}

// const
template<size_t id, typename R, typename T, typename ... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename ... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R (T::*vMethod)(arglist...) const) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R> (T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// volatile
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// const volatile
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const volatile) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// no qualifier
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...)) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// ref
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) &) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// const ref
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// rval ref
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) &&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

// const rval ref
template<size_t id, typename R, typename T, typename... arglist, class = typename std::enable_if<
template<typename MethodType, MethodType Method, typename R, typename T, typename... arglist, class = typename std::enable_if<
std::is_base_of<T, C>::value>::type>
MockingContext<internal::WithCommonVoid_t<R>, arglist...> stub(R(T::*vMethod)(arglist...) const&&) {
auto methodWithoutConstVolatile = reinterpret_cast<internal::WithCommonVoid_t<R>(T::*)(arglist...)>(vMethod);
return impl.template stubMethod<id>(methodWithoutConstVolatile);
return impl.template stubMethod<MethodType, Method>(methodWithoutConstVolatile);
}

DtorMockingContext dtor() {
Expand Down
12 changes: 6 additions & 6 deletions include/fakeit/MockImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ namespace fakeit {
return DataMemberStubbingRoot<T, DataType>();
}

template<size_t id, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
template<typename MethodType, MethodType Method, typename R, typename T, typename ... arglist, class = typename std::enable_if<std::is_base_of<T, C>::value>::type>
MockingContext<R, arglist...> stubMethod(R(T::*vMethod)(arglist...)) {
return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < id, R, arglist... >
return MockingContext<R, arglist...>(new UniqueMethodMockingContextImpl < MethodType, Method, R, arglist... >
(*this, vMethod));
}

Expand Down Expand Up @@ -226,12 +226,12 @@ namespace fakeit {
};


template<size_t id, typename R, typename ... arglist>
template<typename MethodType, MethodType Method, typename R, typename ... arglist>
class UniqueMethodMockingContextImpl : public MethodMockingContextImpl<R, arglist...> {
protected:

RecordedMethodBody<R, arglist...> &getRecordedMethodBody() override {
return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<id>(
return MethodMockingContextBase<R, arglist...>::_mock.template stubMethodIfNotStubbed<MethodType, Method>(
MethodMockingContextBase<R, arglist...>::_mock._proxy,
MethodMockingContextImpl<R, arglist...>::_vMethod);
}
Expand Down Expand Up @@ -323,11 +323,11 @@ namespace fakeit {
return origMethodPtr;
}

template<size_t id, typename R, typename ... arglist>
template<typename MethodType, MethodType Method, typename R, typename ... arglist>
RecordedMethodBody<R, arglist...> &stubMethodIfNotStubbed(DynamicProxy<C, baseclasses...> &proxy,
R (C::*vMethod)(arglist...)) {
if (!proxy.isMethodStubbed(vMethod)) {
proxy.template stubMethod<id>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod));
proxy.template stubMethod<MethodType, Method>(vMethod, createRecordedMethodBody < R, arglist... > (*this, vMethod));
}
Destructible *d = proxy.getMethodMock(vMethod);
RecordedMethodBody<R, arglist...> *methodMock = dynamic_cast<RecordedMethodBody<R, arglist...> *>(d);
Expand Down
12 changes: 6 additions & 6 deletions include/fakeit/Prototype.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,27 @@ namespace fakeit {
using RValRefType = R (C::*)(Args...) &&;
using ConstRValRefType = R (C::*)(Args...) const&&;

static Type get(Type t) {
static constexpr Type get(Type t) {
return t;
}

static ConstType getConst(ConstType t) {
static constexpr ConstType getConst(ConstType t) {
return t;
}

static RefType getRef(RefType t) {
static constexpr RefType getRef(RefType t) {
return t;
}

static ConstRefType getConstRef(ConstRefType t) {
static constexpr ConstRefType getConstRef(ConstRefType t) {
return t;
}

static RValRefType getRValRef(RValRefType t) {
static constexpr RValRefType getRValRef(RValRefType t) {
return t;
}

static ConstRValRefType getConstRValRef(ConstRValRefType t) {
static constexpr ConstRValRefType getConstRValRef(ConstRValRefType t) {
return t;
}

Expand Down
14 changes: 7 additions & 7 deletions include/fakeit/api_macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,25 +39,25 @@
(mock).dtor().setMethodDetails(#mock,"destructor")

#define Method(mock, method) \
(mock).template stub<STUB_ID(__COUNTER__)>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)
(mock).template stub<decltype(&MOCK_TYPE(mock)::method), &MOCK_TYPE(mock)::method>(&MOCK_TYPE(mock)::method).setMethodDetails(#mock,#method)

#define OverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstOverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define RefOverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define RValRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define ConstRValRefOverloadedMethod(mock, method, prototype) \
(mock).template stub<STUB_ID(__COUNTER__)>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)
(mock).template stub<decltype(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )), &MOCK_TYPE(mock)::method>(CONST_R_VAL_REF_OVERLOADED_METHOD_PTR( mock , method, prototype )).setMethodDetails(#mock,#method)

#define Verify(...) \
Verify( __VA_ARGS__ ).setFileInfo(__FILE__, __LINE__, __func__)
Expand Down
71 changes: 39 additions & 32 deletions include/mockutils/DynamicProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,52 @@

namespace fakeit {

class InvocationHandlers : public InvocationHandlerCollection {
std::vector<std::shared_ptr<Destructible>> &_methodMocks;
std::vector<size_t> &_offsets;
namespace details {
template<typename MethodType, MethodType Method>
void funcId() {}

unsigned int getOffset(size_t id) const
{
unsigned int offset = 0;
for (; offset < _offsets.size(); offset++) {
// "_methodMocks[offset] != nullptr" checked to guarantee that "_offsets[offset]" was really set and
// doesn't just contain the default id.
if (_offsets[offset] == id && _methodMocks[offset] != nullptr) {
break;
inline void funcIdDestructor() {}

inline void funcIdNotStubbed() {}
}

template<typename C, typename ... baseclasses>
struct DynamicProxy {

class InvocationHandlers : public InvocationHandlerCollection {
std::vector<std::shared_ptr<Destructible>> &_methodMocks;
std::vector<MethodIdType> &_offsets;

unsigned int getOffset(MethodIdType id) const
{
unsigned int offset = 0;
for (; offset < _offsets.size(); offset++) {
if (_offsets[offset] == id) {
break;
}
}
return offset;
}
return offset;
}

public:
InvocationHandlers(std::vector<std::shared_ptr<Destructible>> &methodMocks, std::vector<size_t> &offsets)
: _methodMocks(methodMocks), _offsets(offsets) {
}

Destructible *getInvocatoinHandlerPtrById(size_t id) override {
unsigned int offset = getOffset(id);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}
public:
InvocationHandlers(std::vector<std::shared_ptr<Destructible>> &methodMocks, std::vector<MethodIdType> &offsets)
: _methodMocks(methodMocks), _offsets(offsets) {
}

};
Destructible *getInvocatoinHandlerPtrById(MethodIdType id) override {
unsigned int offset = getOffset(id);
std::shared_ptr<Destructible> ptr = _methodMocks[offset];
return ptr.get();
}

template<typename C, typename ... baseclasses>
struct DynamicProxy {
};

static_assert(std::is_polymorphic<C>::value, "DynamicProxy requires a polymorphic type");

DynamicProxy(C &inst) :
_instancePtr(&inst),
_methodMocks(VTUtils::getVTSize<C>()),
_offsets(VTUtils::getVTSize<C>(), std::numeric_limits<size_t>::max()),
_offsets(VTUtils::getVTSize<C>(), &details::funcIdNotStubbed),
_invocationHandlers(_methodMocks, _offsets) {
_originalVt.copyFrom(VirtualTable<C, baseclasses...>::getVTable(*_instancePtr));
_originalVt.setCookie(InvocationHandlerCollection::VtCookieIndex, &_invocationHandlers);
Expand Down Expand Up @@ -110,11 +117,11 @@ namespace fakeit {
{
}

template<size_t id, typename R, typename ... arglist>
template<typename MethodType, MethodType Method, typename R, typename ... arglist>
void stubMethod(R(C::*vMethod)(arglist...), MethodInvocationHandler<R, arglist...> *methodInvocationHandler) {
auto offset = VTUtils::getOffset(vMethod);
MethodProxyCreator<R, arglist...> creator;
bind(creator.template createMethodProxy<id + 1>(offset), methodInvocationHandler);
bind(creator.template createMethodProxy<&details::funcId<MethodType, Method>>(offset), methodInvocationHandler);
}

void stubDtor(MethodInvocationHandler<void> *methodInvocationHandler) {
Expand All @@ -127,9 +134,9 @@ namespace fakeit {
// For GCC / Clang, the destructor is directly called, like normal methods, so we use the member-function
// version.
#ifdef _MSC_VER
bindDtor(creator.createMethodProxyStatic<0>(offset), methodInvocationHandler);
bindDtor(creator.createMethodProxyStatic<&details::funcIdDestructor>(offset), methodInvocationHandler);
#else
bindDtor(creator.createMethodProxy<0>(offset), methodInvocationHandler);
bindDtor(creator.createMethodProxy<&details::funcIdDestructor>(offset), methodInvocationHandler);
#endif
}

Expand Down Expand Up @@ -219,7 +226,7 @@ namespace fakeit {
//
std::vector<std::shared_ptr<Destructible>> _methodMocks;
std::vector<std::shared_ptr<Destructible>> _members;
std::vector<size_t> _offsets;
std::vector<MethodIdType> _offsets;
InvocationHandlers _invocationHandlers;

FakeObject<C, baseclasses...> &getFake() {
Expand Down
10 changes: 6 additions & 4 deletions include/mockutils/MethodProxy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@

namespace fakeit {

using MethodIdType = void(*)();

struct MethodProxy {

MethodProxy(size_t id, unsigned int offset, void *vMethod) :
MethodProxy(MethodIdType id, unsigned int offset, void *vMethod) :
_id(id),
_offset(offset),
_vMethod(vMethod) {
Expand All @@ -16,7 +18,7 @@ namespace fakeit {
return _offset;
}

size_t getId() const {
MethodIdType getId() const {
return _id;
}

Expand All @@ -25,8 +27,8 @@ namespace fakeit {
}

private:
size_t _id;
MethodIdType _id;
unsigned int _offset;
void *_vMethod;
};
}
}
Loading

0 comments on commit fe86008

Please sign in to comment.