File indexing completed on 2024-09-22 04:53:11

0001 /*
0002  * SPDX-FileCopyrightText: 2008 Trevor Pounds
0003  * SPDX-License-Identifier: MIT
0004  */
0005 
0006 #ifndef __MOCKITOPP_PROXY_VFUNCTION_HPP__
0007 #define __MOCKITOPP_PROXY_VFUNCTION_HPP__
0008 
0009 #include <mockitopp/detail/stubbing/dynamic_vfunction.hpp>
0010 #include <mockitopp/detail/util/horrible_cast.hpp>
0011 #include <mockitopp/detail/util/remove_member_function_pointer_cv.hpp>
0012 
0013 namespace mockitopp
0014 {
0015    namespace detail
0016    {
0017       template <int OFFSET, typename T> struct proxy_vfunction;
0018 
0019       template <int OFFSET, typename R, typename C >
0020       struct proxy_vfunction<OFFSET, R (C::*)()>
0021       {
0022          void* __PAD_FOR_MOCK_vptr;
0023          dynamic_vfunction<R (C::*)()>*
0024             __PAD_FOR_MOCK_spys[50];
0025 
0026          R invoke()
0027             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(); }
0028       };
0029 
0030       template <int OFFSET, typename R, typename C , typename A0>
0031       struct proxy_vfunction<OFFSET, R (C::*)(A0)>
0032       {
0033          void* __PAD_FOR_MOCK_vptr;
0034          dynamic_vfunction<R (C::*)(A0)>*
0035             __PAD_FOR_MOCK_spys[50];
0036 
0037          R invoke(A0 a0)
0038             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0); }
0039       };
0040 
0041       template <int OFFSET, typename R, typename C , typename A0, typename A1>
0042       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1)>
0043       {
0044          void* __PAD_FOR_MOCK_vptr;
0045          dynamic_vfunction<R (C::*)(A0, A1)>*
0046             __PAD_FOR_MOCK_spys[50];
0047 
0048          R invoke(A0 a0, A1 a1)
0049             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1); }
0050       };
0051 
0052       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2>
0053       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2)>
0054       {
0055          void* __PAD_FOR_MOCK_vptr;
0056          dynamic_vfunction<R (C::*)(A0, A1, A2)>*
0057             __PAD_FOR_MOCK_spys[50];
0058 
0059          R invoke(A0 a0, A1 a1, A2 a2)
0060             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2); }
0061       };
0062 
0063       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3>
0064       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3)>
0065       {
0066          void* __PAD_FOR_MOCK_vptr;
0067          dynamic_vfunction<R (C::*)(A0, A1, A2, A3)>*
0068             __PAD_FOR_MOCK_spys[50];
0069 
0070          R invoke(A0 a0, A1 a1, A2 a2, A3 a3)
0071             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3); }
0072       };
0073 
0074       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4>
0075       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4)>
0076       {
0077          void* __PAD_FOR_MOCK_vptr;
0078          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4)>*
0079             __PAD_FOR_MOCK_spys[50];
0080 
0081          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4)
0082             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4); }
0083       };
0084 
0085       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
0086       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5)>
0087       {
0088          void* __PAD_FOR_MOCK_vptr;
0089          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5)>*
0090             __PAD_FOR_MOCK_spys[50];
0091 
0092          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5)
0093             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5); }
0094       };
0095 
0096       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
0097       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6)>
0098       {
0099          void* __PAD_FOR_MOCK_vptr;
0100          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6)>*
0101             __PAD_FOR_MOCK_spys[50];
0102 
0103          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6)
0104             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6); }
0105       };
0106 
0107       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
0108       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7)>
0109       {
0110          void* __PAD_FOR_MOCK_vptr;
0111          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7)>*
0112             __PAD_FOR_MOCK_spys[50];
0113 
0114          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7)
0115             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7); }
0116       };
0117 
0118       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
0119       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)>
0120       {
0121          void* __PAD_FOR_MOCK_vptr;
0122          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8)>*
0123             __PAD_FOR_MOCK_spys[50];
0124 
0125          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8)
0126             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
0127       };
0128 
0129       template <int OFFSET, typename R, typename C , typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
0130       struct proxy_vfunction<OFFSET, R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)>
0131       {
0132          void* __PAD_FOR_MOCK_vptr;
0133          dynamic_vfunction<R (C::*)(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)>*
0134             __PAD_FOR_MOCK_spys[50];
0135 
0136          R invoke(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9)
0137             { return __PAD_FOR_MOCK_spys[OFFSET]->invoke(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
0138       };
0139 
0140 
0141       template <typename M>
0142       struct proxy_vfunction_factory
0143       {
0144          static void* get(M ptr2member)
0145          {
0146             proxy_vfunction_factory s;
0147 #pragma GCC diagnostic push
0148 #pragma GCC diagnostic ignored "-Wcast-function-type"
0149             return (s.*reinterpret_cast<void* (proxy_vfunction_factory::*)()>(ptr2member))();
0150 #pragma GCC diagnostic pop
0151          }
0152 
0153          virtual void* offset0() { return horrible_cast<void*>(&proxy_vfunction<0, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0154          virtual void* offset1() { return horrible_cast<void*>(&proxy_vfunction<1, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0155          virtual void* offset2() { return horrible_cast<void*>(&proxy_vfunction<2, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0156          virtual void* offset3() { return horrible_cast<void*>(&proxy_vfunction<3, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0157          virtual void* offset4() { return horrible_cast<void*>(&proxy_vfunction<4, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0158          virtual void* offset5() { return horrible_cast<void*>(&proxy_vfunction<5, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0159          virtual void* offset6() { return horrible_cast<void*>(&proxy_vfunction<6, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0160          virtual void* offset7() { return horrible_cast<void*>(&proxy_vfunction<7, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0161          virtual void* offset8() { return horrible_cast<void*>(&proxy_vfunction<8, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0162          virtual void* offset9() { return horrible_cast<void*>(&proxy_vfunction<9, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0163          virtual void* offset10() { return horrible_cast<void*>(&proxy_vfunction<10, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0164          virtual void* offset11() { return horrible_cast<void*>(&proxy_vfunction<11, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0165          virtual void* offset12() { return horrible_cast<void*>(&proxy_vfunction<12, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0166          virtual void* offset13() { return horrible_cast<void*>(&proxy_vfunction<13, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0167          virtual void* offset14() { return horrible_cast<void*>(&proxy_vfunction<14, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0168          virtual void* offset15() { return horrible_cast<void*>(&proxy_vfunction<15, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0169          virtual void* offset16() { return horrible_cast<void*>(&proxy_vfunction<16, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0170          virtual void* offset17() { return horrible_cast<void*>(&proxy_vfunction<17, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0171          virtual void* offset18() { return horrible_cast<void*>(&proxy_vfunction<18, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0172          virtual void* offset19() { return horrible_cast<void*>(&proxy_vfunction<19, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0173          virtual void* offset20() { return horrible_cast<void*>(&proxy_vfunction<20, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0174          virtual void* offset21() { return horrible_cast<void*>(&proxy_vfunction<21, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0175          virtual void* offset22() { return horrible_cast<void*>(&proxy_vfunction<22, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0176          virtual void* offset23() { return horrible_cast<void*>(&proxy_vfunction<23, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0177          virtual void* offset24() { return horrible_cast<void*>(&proxy_vfunction<24, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0178          virtual void* offset25() { return horrible_cast<void*>(&proxy_vfunction<25, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0179          virtual void* offset26() { return horrible_cast<void*>(&proxy_vfunction<26, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0180          virtual void* offset27() { return horrible_cast<void*>(&proxy_vfunction<27, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0181          virtual void* offset28() { return horrible_cast<void*>(&proxy_vfunction<28, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0182          virtual void* offset29() { return horrible_cast<void*>(&proxy_vfunction<29, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0183          virtual void* offset30() { return horrible_cast<void*>(&proxy_vfunction<30, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0184          virtual void* offset31() { return horrible_cast<void*>(&proxy_vfunction<31, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0185          virtual void* offset32() { return horrible_cast<void*>(&proxy_vfunction<32, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0186          virtual void* offset33() { return horrible_cast<void*>(&proxy_vfunction<33, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0187          virtual void* offset34() { return horrible_cast<void*>(&proxy_vfunction<34, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0188          virtual void* offset35() { return horrible_cast<void*>(&proxy_vfunction<35, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0189          virtual void* offset36() { return horrible_cast<void*>(&proxy_vfunction<36, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0190          virtual void* offset37() { return horrible_cast<void*>(&proxy_vfunction<37, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0191          virtual void* offset38() { return horrible_cast<void*>(&proxy_vfunction<38, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0192          virtual void* offset39() { return horrible_cast<void*>(&proxy_vfunction<39, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0193          virtual void* offset40() { return horrible_cast<void*>(&proxy_vfunction<40, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0194          virtual void* offset41() { return horrible_cast<void*>(&proxy_vfunction<41, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0195          virtual void* offset42() { return horrible_cast<void*>(&proxy_vfunction<42, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0196          virtual void* offset43() { return horrible_cast<void*>(&proxy_vfunction<43, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0197          virtual void* offset44() { return horrible_cast<void*>(&proxy_vfunction<44, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0198          virtual void* offset45() { return horrible_cast<void*>(&proxy_vfunction<45, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0199          virtual void* offset46() { return horrible_cast<void*>(&proxy_vfunction<46, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0200          virtual void* offset47() { return horrible_cast<void*>(&proxy_vfunction<47, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0201          virtual void* offset48() { return horrible_cast<void*>(&proxy_vfunction<48, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0202          virtual void* offset49() { return horrible_cast<void*>(&proxy_vfunction<49, typename remove_member_function_pointer_cv<M>::type>::invoke); }
0203 
0204          virtual ~proxy_vfunction_factory() {}
0205       };
0206    } // namespace detail
0207 } // namespace mockitopp
0208 
0209 #endif //__MOCKITOPP_PROXY_VFUNCTION_HPP__