@@ -111,7 +111,17 @@ class CVTHook : public CMemory
111111 // to the original implementation’s logic. For example, in your hooked method body,
112112 // you can call `hookInstance.Call(...);` to execute the original virtual method with
113113 // the supplied arguments. If not called in the hook, the original logic will not run.
114- R Call (Args... args) const { return GetOrigin<Function_t>()(args...); }
114+ R Call (Args... args) const
115+ {
116+ if constexpr (std::is_void_v<R>)
117+ {
118+ GetOrigin<Function_t>()(args...);
119+
120+ return ;
121+ }
122+
123+ return GetOrigin<Function_t>()(args...);
124+ }
115125
116126protected: // Implementation methods.
117127 void HookImpl (Function_t pfnTarget) noexcept
@@ -174,24 +184,28 @@ class CVTFHook : public CVTHook<R, Args...>
174184 inline static Function_t sm_callback;
175185}; // class CVTFHook<R, Args...>
176186
177- // A template class represents generic manager for multiple virtual‐table hooks of the same signature.
178- // Template Parameter:
179- // T — A hook element type, which must:
187+ // A template class represents a generic manager for multiple virtual-table hooks of the same signature.
188+ // Template Parameters:
189+ // TH - A hook element template (e.g., CVTHook or CVTFHook).
190+ // R - Return type of the virtual method.
191+ // C - Pointer type of the class instance (this pointer).
192+ // Args - Remaining argument types.
193+ // Hook element type must:
180194// * Define a nested alias Function_t (e.g., R(*)(Args...)).
181195// * Provide methods:
182196// - void Hook(CVirtualTable, std::ptrdiff_t, Function_t)
183197// - R Call(C*, Args...) (or similar overloads)
184198// - bool Unhook(), etc.
185- // Typical instantiations might be CVTHook<R,Args...> or CVTFHook<R,Args...>.
186- template <class T >
199+ // Typical instantiations might be CVTHook<R, Args...> or CVTFHook<R, Args...>.
200+ template <template < typename , typename ...> class TH , typename R, typename C, typename ...Args >
187201class CVTMHookBase
188202{
189203public:
190204 CVTMHookBase () = default ;
191205 CVTMHookBase (const CVTMHookBase &other) = delete ;
192206 CVTMHookBase (CVTMHookBase &&other) = default ;
193207
194- using Element_t = T ;
208+ using Element_t = TH<R, C, Args...> ;
195209 using Function_t = typename Element_t::Function_t;
196210
197211public:
@@ -219,22 +233,28 @@ class CVTMHookBase
219233 return m_storage.emplace (pVTable, std::move (vth));
220234 }
221235
222- template <typename R, typename C, typename ...Args>
223236 R Call (C pThis, Args... args)
224237 {
225238 auto found = Find (CVirtualTable (pThis));
226239
227240 assert (found.first != found.second );
228241
242+ if constexpr (std::is_void_v<R>)
243+ {
244+ found.first ->second .Call (pThis, args...);
245+
246+ return ;
247+ }
248+
229249 return found.first ->second .Call (pThis, args...);
230250 }
231251
232252 // Returns a vector containing the return values from each hook’s Call() invocation,
233253 // in order of insertion. If no hooks were found for that vtable, returns an empty vector.
234- template <typename R, typename C , typename ...Args >
235- std::vector<R > CallAll (C pThis, Args... args)
254+ template <typename Ret = R , typename = std:: enable_if_t <!std::is_void_v<Ret>> >
255+ std::vector<Ret > CallAll (C pThis, Args... args)
236256 {
237- std::vector<R > results;
257+ std::vector<Ret > results;
238258
239259 auto found = Find (CVirtualTable (pThis));
240260
@@ -250,36 +270,16 @@ class CVTMHookBase
250270 return results;
251271 }
252272
253- // Returns true if at least one hook was executed; false if no hooks were found for that vtable.
254- template <typename C, typename ...Args>
255- bool CallAllNoReturn (C pThis, Args... args)
256- {
257- auto found = Find (CVirtualTable (pThis));
258-
259- if (found.first == found.second )
260- {
261- return false ;
262- }
263-
264- // results.reserve(vhooks.size());
265-
266- for (auto it = found.first ; it != found.second ; it++)
267- {
268- it->second .Call (pThis, args...);
269- }
270-
271- return true ;
272- }
273273 // erases all hook elements associated with that vtable.
274274 // - Returns the number of elements removed (std::size_t).
275275 std::size_t RemoveHook (CVirtualTable pVTable) { return m_storage.erase (pVTable); }
276276
277277private:
278278 std::multimap<CVirtualTable, Element_t> m_storage;
279- }; // class CVTMHookBase<T, FUNC >
279+ }; // class CVTMHookBase<TH, R, C, Args... >
280280
281281template <typename R, typename ...Args>
282- using CVTMHook = CVTMHookBase<CVTHook< R, Args...> >;
282+ using CVTMHook = CVTMHookBase<CVTHook, R, Args...>;
283283
284284// A template class manages multiple virtual‐table hooks per class instance, where each hook can
285285// execute multiple callbacks (std::function) when the original virtual method is invoked.
0 commit comments