From a2abfc3f0309a35b34f54f6c07b8d21f06868933 Mon Sep 17 00:00:00 2001 From: Substitute Date: Fri, 10 Mar 2023 01:34:23 -0500 Subject: [PATCH] Move namespaces into their own classes, additional code clean up. --- concepts.h | 22 ++++++ function_ptr.h | 175 +------------------------------------------ function_signature.h | 109 +++++++++++++++++++++++++++ moar_ptr.h | 5 ++ type_traits.h | 53 +++++++++++++ types.h | 23 ++++++ 6 files changed, 214 insertions(+), 173 deletions(-) create mode 100644 concepts.h create mode 100644 function_signature.h create mode 100644 type_traits.h create mode 100644 types.h diff --git a/concepts.h b/concepts.h new file mode 100644 index 0000000..1727378 --- /dev/null +++ b/concepts.h @@ -0,0 +1,22 @@ +#pragma once +#include +#include +#include "moar_ptr.h" + +namespace moar +{ + namespace concepts + { + template + concept Function = std::is_function_v; + + template + concept CallingConvention = std::derived_from; + + template + concept Variadic = std::is_same_v || std::is_same_v; + + template + concept CommonType = CallingConvention || Variadic; + } +} diff --git a/function_ptr.h b/function_ptr.h index 1e1fbb9..5e1132a 100644 --- a/function_ptr.h +++ b/function_ptr.h @@ -6,175 +6,13 @@ #define WIN32_LEAN_AND_MEAN #include -#pragma region Definitions - -#if defined(__GNUC__) || defined(__clang__) -#define CC_CDECL __attribute__((cdecl)) -#define CC_STDCALL __attribute__((stdcall)) -#define CC_THISCALL __attribute__((thiscall)) -#define CC_FASTCALL __attribute__((fastcall)) -#define CC_VECTORCALL __attribute__((vectorcall)) -#if defined(__INTEL_COMPILER) -#define CC_REGCALL __attribute__((regcall)) -#else -#define CC_REGCALL CC_CDECL -#endif -#elif defined(_MSC_VER) || defined(__INTEL_COMPILER) -#define CC_CDECL __cdecl -#define CC_STDCALL __stdcall -#define CC_THISCALL __thiscall -#define CC_FASTCALL __fastcall -#define CC_VECTORCALL __vectorcall -#if defined(__INTEL_COMPILER) -#define CC_REGCALL __regcall -#else -#define CC_REGCALL CC_CDECL -#endif -#else -#define CC_CDECL -#define CC_STDCALL -#define CC_THISCALL -#define CC_FASTCALL -#define CC_VECTORCALL -#define CC_REGCALL -#endif -#if defined(__clang__ ) /* Clang does not support B(A)(C...) syntax, only A B(C...) and refuses to compile otherwise. */ -#define FUNCTION_SIGNATURE(x,y,z) x y (z) -#define FUNCTION_SIGNATURE_VA(x,y,z) x y (z, ...) -#elif defined(__GNUC__) || defined(_MSC_VER) || defined(__INTEL_COMPILER) /* GCC Supports A B(C...) and B(A)(C...) but produces wrong T* for T under A B(C...) */ -#define FUNCTION_SIGNATURE(x,y,z) y(x)(z) -#define FUNCTION_SIGNATURE_VA(x,y,z) y(x)(z,...) -#endif - -#pragma endregion - namespace moar { - namespace types - { - struct variadic_t {}; - - struct calling_convention {}; - struct cdecl_t : calling_convention {}; - struct stdcall_t : calling_convention {}; - struct thiscall_t : calling_convention {}; - struct fastcall_t : calling_convention {}; - struct vectorcall_t : calling_convention {}; - struct regcall_t : calling_convention {}; - - using default_variadic = void; - using default_calling_convention = cdecl_t; - } - namespace concepts - { - template - concept Function = std::is_function_v; - - template - concept CallingConvention = std::derived_from; - - template - concept Variadic = std::is_same_v || std::is_same_v; - - template - concept CommonType = CallingConvention || Variadic; - } -#pragma region Helpers -#if defined(__clang__ ) /* Ignore attribute warnings here to shut Clang up. */ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wignored-attributes" -#endif - template - struct signature { - static_assert(sizeof(T2) == 0 || sizeof(T3) == 0, "Illegal Function Signature"); - using type = void; - }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_CDECL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE_VA(CC_CDECL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_STDCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE_VA(CC_STDCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_THISCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_FASTCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE_VA(CC_FASTCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_VECTORCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE(CC_REGCALL, RT, A...); }; - - template - struct signature { using type = FUNCTION_SIGNATURE_VA(CC_REGCALL, RT, A...); }; - - namespace type_traits - { - /// - /// Selects T1 or T2 depending on if T1 or T2 is Variadic - /// - template - struct SelectVariadic { - static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectVariadic (T1 and/or T2 missing.)"); - using type = void; - }; - - template - struct SelectVariadic { using type = T2; }; - - template - struct SelectVariadic { using type = T1; }; - - /// - /// Selects T1 or T2 depending on if T1 or T2 is a Calling Convention - /// - template - struct SelectCallingConvention { - static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectCallingConvention (T1 and/or T2 missing.)"); - using type = void; - }; - - template - struct SelectCallingConvention { using type = T1; }; - - template - struct SelectCallingConvention { using type = T2; }; - - template - struct SelectDefaultT3 { - static_assert(sizeof(T) == 0, "Incorrect Usage of SelectDefaultT3 (T missing.)"); - using type = void; - }; - - template - struct SelectDefaultT3 { using type = types::default_calling_convention; }; - - template - struct SelectDefaultT3 { using type = types::default_variadic; }; - - } -#if defined(__clang__) /* Clang does not support B(A)(C...) syntax, only A B(C...) and refuses to compile otherwise. */ -#pragma clang diagnostic pop -#endif -#pragma endregion - template::type> class function_ptr {}; template - class function_ptr : public extern_ptr::type, typename type_traits::SelectVariadic::type>::type> /* typename not declared yet. */ + class function_ptr : public extern_ptr::type, typename type_traits::SelectVariadic::type>::type> /* typename not declared yet. */ { public: /// @@ -260,7 +98,7 @@ namespace moar return mutable_ptr(args..., vargs...); } private: - using base = extern_ptr::type, typename type_traits::SelectVariadic::type>::type>; + using base = extern_ptr::type, typename type_traits::SelectVariadic::type>::type>; base::element_type* mutable_ptr = 0; @@ -277,13 +115,4 @@ namespace moar { std::size_t operator()(moar::function_ptr const& p) const noexcept { return std::hash{}(p.get()); } }; - -#undef CC_CDECL -#undef CC_STDCALL -#undef CC_THISCALL -#undef CC_FASTCALL -#undef CC_VECTORCALL -#undef CC_REGCALL -#undef FUNCTION_SIGNATURE -#undef FUNCTION_SIGNATURE_VA } diff --git a/function_signature.h b/function_signature.h new file mode 100644 index 0000000..871c5d0 --- /dev/null +++ b/function_signature.h @@ -0,0 +1,109 @@ +#pragma once +#include +#include +#include "moar_ptr.h" + +#pragma region Definitions + +#if defined(__GNUC__) || defined(__clang__) +#define CC_CDECL __attribute__((cdecl)) +#define CC_STDCALL __attribute__((stdcall)) +#define CC_THISCALL __attribute__((thiscall)) +#define CC_FASTCALL __attribute__((fastcall)) +#define CC_VECTORCALL __attribute__((vectorcall)) +#if defined(__INTEL_COMPILER) +#define CC_REGCALL __attribute__((regcall)) +#else +#define CC_REGCALL CC_CDECL +#endif +#elif defined(_MSC_VER) || defined(__INTEL_COMPILER) +#define CC_CDECL __cdecl +#define CC_STDCALL __stdcall +#define CC_THISCALL __thiscall +#define CC_FASTCALL __fastcall +#define CC_VECTORCALL __vectorcall +#if defined(__INTEL_COMPILER) +#define CC_REGCALL __regcall +#else +#define CC_REGCALL CC_CDECL +#endif +#else +#define CC_CDECL +#define CC_STDCALL +#define CC_THISCALL +#define CC_FASTCALL +#define CC_VECTORCALL +#define CC_REGCALL +#endif +#if defined(__clang__ ) /* Clang does not support B(A)(C...) syntax, only A B(C...) and refuses to compile otherwise. */ +#define FUNCTION_SIGNATURE(x,y,z) x y (z) +#define FUNCTION_SIGNATURE_VA(x,y,z) x y (z, ...) +#elif defined(__GNUC__) || defined(_MSC_VER) || defined(__INTEL_COMPILER) /* GCC Supports A B(C...) and B(A)(C...) but produces wrong T* for T under A B(C...) */ +#define FUNCTION_SIGNATURE(x,y,z) y(x)(z) +#define FUNCTION_SIGNATURE_VA(x,y,z) y(x)(z,...) +#endif + +#if defined(__clang__ ) /* Ignore attribute warnings here to shut Clang up. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-attributes" +#endif + +#pragma endregion + + +namespace moar +{ + template + struct function_signature { + static_assert(sizeof(T2) == 0 || sizeof(T3) == 0, "Illegal Function Signature"); + using type = void; + }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_CDECL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE_VA(CC_CDECL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_STDCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE_VA(CC_STDCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_THISCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_FASTCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE_VA(CC_FASTCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_VECTORCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE(CC_REGCALL, RT, A...); }; + + template + struct function_signature { using type = FUNCTION_SIGNATURE_VA(CC_REGCALL, RT, A...); }; +} + + +#pragma region Undefinitions + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +#undef CC_CDECL +#undef CC_STDCALL +#undef CC_THISCALL +#undef CC_FASTCALL +#undef CC_VECTORCALL +#undef CC_REGCALL +#undef FUNCTION_SIGNATURE +#undef FUNCTION_SIGNATURE_VA + +#pragma endregion \ No newline at end of file diff --git a/moar_ptr.h b/moar_ptr.h index 61861a7..2b5f599 100644 --- a/moar_ptr.h +++ b/moar_ptr.h @@ -1,3 +1,8 @@ #pragma once +#include "types.h" +#include "concepts.h" +#include "type_traits.h" + #include "extern_ptr.h" +#include "function_signature.h" #include "function_ptr.h" diff --git a/type_traits.h b/type_traits.h new file mode 100644 index 0000000..9176f16 --- /dev/null +++ b/type_traits.h @@ -0,0 +1,53 @@ +#pragma once +#include +#include +#include "moar_ptr.h" + +namespace moar +{ + namespace type_traits + { + /// + /// Selects T1 or T2 depending on if T1 or T2 is Variadic + /// + template + struct SelectVariadic { + static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectVariadic (T1 and/or T2 missing.)"); + using type = void; + }; + + template + struct SelectVariadic { using type = T2; }; + + template + struct SelectVariadic { using type = T1; }; + + /// + /// Selects T1 or T2 depending on if T1 or T2 is a Calling Convention + /// + template + struct SelectCallingConvention { + static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectCallingConvention (T1 and/or T2 missing.)"); + using type = void; + }; + + template + struct SelectCallingConvention { using type = T1; }; + + template + struct SelectCallingConvention { using type = T2; }; + + template + struct SelectDefaultT3 { + static_assert(sizeof(T) == 0, "Incorrect Usage of SelectDefaultT3 (T missing.)"); + using type = void; + }; + + template + struct SelectDefaultT3 { using type = types::default_calling_convention; }; + + template + struct SelectDefaultT3 { using type = types::default_variadic; }; + + } +} diff --git a/types.h b/types.h new file mode 100644 index 0000000..b96e35a --- /dev/null +++ b/types.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include "moar_ptr.h" + +namespace moar +{ + namespace types + { + struct variadic_t {}; + + struct calling_convention {}; + struct cdecl_t : calling_convention {}; + struct stdcall_t : calling_convention {}; + struct thiscall_t : calling_convention {}; + struct fastcall_t : calling_convention {}; + struct vectorcall_t : calling_convention {}; + struct regcall_t : calling_convention {}; + + using default_variadic = void; + using default_calling_convention = cdecl_t; + } +}