// === detail/size_getter_defs.hpp === #pragma once #include // for std::declval() #include "va_defs.hpp" #define HAS_MFUNC_(T, func, fdef) has_mem_func_##func() #define DEF_FUNC_TEMPL_IMPL(fdef, func) template > static constexpr \ auto fname(const T &val) -> decltype(val.func()) { return val.func(); } #define NO_MFUNC_3(T, fdef, func) && !HAS_MFUNC_(T, func, fdef) #define NO_MFUNC_4(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_3(T, fdef, __VA_ARGS__) #define NO_MFUNC_5(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_4(T, fdef, __VA_ARGS__) #define NO_MFUNC_6(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_5(T, fdef, __VA_ARGS__) #define NO_MFUNC_7(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_6(T, fdef, __VA_ARGS__) #define NO_MFUNC_8(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_7(T, fdef, __VA_ARGS__) #define NO_MFUNC_9(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_8(T, fdef, __VA_ARGS__) #define NO_MFUNC_10(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_9(T, fdef, __VA_ARGS__) #define NO_MFUNC_11(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_10(T, fdef, __VA_ARGS__) #define NO_MFUNC_12(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_11(T, fdef, __VA_ARGS__) #define NO_MFUNC_13(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_12(T, fdef, __VA_ARGS__) #define NO_MFUNC_14(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_13(T, fdef, __VA_ARGS__) #define NO_MFUNC_15(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_14(T, fdef, __VA_ARGS__) #define NO_MFUNC_16(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_15(T, fdef, __VA_ARGS__) #define NO_MFUNC_17(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_16(T, fdef, __VA_ARGS__) #define NO_MFUNC_18(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_17(T, fdef, __VA_ARGS__) #define NO_MFUNC_19(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_18(T, fdef, __VA_ARGS__) #define NO_MFUNC_20(T, fdef, func, ...) && !HAS_MFUNC_(T, func, fdef) NO_MFUNC_19(T, fdef, __VA_ARGS__) #define DEF_HAS_MFUNC(fname) template \ static constexpr auto has_mem_func_##fname() -> \ decltype(std::declval().fname(), true) { \ return std::is_same::value; } \ template \ static constexpr auto has_mem_func_##fname(Args...) -> bool { return false; } #define DEF_FUNC_(fdef, fname, func, ...) DEF_FUNC_TEMPL_IMPL(fdef, func) \ VA_NUM_MACRO_CALL2(NO_MFUNC_, T, fdef, __VA_ARGS__) \ DEF_FUNC_IMPL_IMPL(fname, func) #define DEF_FUNC_3(fdef, fname, func) DEF_HAS_MFUNC(func) DEF_FUNC_TEMPL_IMPL(fdef, func) DEF_FUNC_IMPL_IMPL(fname, func) #define DEF_FUNC_4(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_3(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_5(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_4(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_6(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_5(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_7(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_6(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_8(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_7(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_9(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_8(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_10(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_9(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_11(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_10(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_12(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_11(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_13(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_12(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_14(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_13(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_15(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_14(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_16(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_15(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_17(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_16(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_18(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_17(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_19(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_18(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNC_20(fdef, fname, func, ...) DEF_HAS_MFUNC(func) DEF_FUNC_19(fdef, fname, __VA_ARGS__) DEF_FUNC_(fdef, fname, func, __VA_ARGS__) #define DEF_FUNCS(fdef, fname, ...) VA_NUM_MACRO_CALL(DEF_FUNC_, fdef, fname, fname, __VA_ARGS__)