Here is an answer that can detect it at compile time and create a boolean. It works by creating a template function with the same name in the namespace, and then using that namespace inside the is_defined()
function. If real glDrawArraysIndirect()
exists, it will give preference to the pattern. If you comment out the first glDrawArraysIndirect()
declaration, a static statement below will be triggered.
Test on godbolt
#include <type_traits> enum GLenum {}; void glDrawArraysIndirect(GLenum, const void*); namespace detail { struct dummy; template<typename T> dummy& glDrawArraysIndirect(T, const void*); } constexpr bool is_defined() { using namespace detail; using ftype = decltype(glDrawArraysIndirect(GLenum(), nullptr)); return std::is_same<ftype, void>(); } static_assert(is_defined(), "not defined");
With a little tweaking, you can make your custom function a template and use a similar trick
ideone.com
#include <type_traits> #include <iostream> //#define USE_REAL enum GLenum {TEST}; typedef void (*func_type)(GLenum, const void*); #ifdef USE_REAL void glDrawArraysIndirect(GLenum, const void*); #endif namespace detail { struct dummy {}; template<typename T = dummy> void glDrawArraysIndirect(GLenum, const void*, T = T()) { std::cout << "In placeholder function" << std::endl; } } void wrapDraw(GLenum x, const void* y) { using namespace detail; glDrawArraysIndirect(x, y); } #ifdef USE_REAL void glDrawArraysIndirect(GLenum, const void*) { std::cout << "In real function" << std::endl; } #endif int main() { wrapDraw(TEST, nullptr); }
source share