-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move namespaces into their own classes, additional code clean up.
- Loading branch information
1 parent
1a063c4
commit a2abfc3
Showing
6 changed files
with
214 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#pragma once | ||
#include <concepts> | ||
#include <functional> | ||
#include "moar_ptr.h" | ||
|
||
namespace moar | ||
{ | ||
namespace concepts | ||
{ | ||
template<typename T> | ||
concept Function = std::is_function_v<T>; | ||
|
||
template<typename T> | ||
concept CallingConvention = std::derived_from<T, types::calling_convention>; | ||
|
||
template<typename T> | ||
concept Variadic = std::is_same_v<T, types::variadic_t> || std::is_same_v<T, void>; | ||
|
||
template<typename T> | ||
concept CommonType = CallingConvention<T> || Variadic<T>; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#pragma once | ||
#include <concepts> | ||
#include <functional> | ||
#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<concepts::Function T1, concepts::CallingConvention T2, concepts::Variadic T3> | ||
struct function_signature { | ||
static_assert(sizeof(T2) == 0 || sizeof(T3) == 0, "Illegal Function Signature"); | ||
using type = void; | ||
}; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::cdecl_t, void> { using type = FUNCTION_SIGNATURE(CC_CDECL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::cdecl_t, types::variadic_t> { using type = FUNCTION_SIGNATURE_VA(CC_CDECL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::stdcall_t, void> { using type = FUNCTION_SIGNATURE(CC_STDCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::stdcall_t, types::variadic_t> { using type = FUNCTION_SIGNATURE_VA(CC_STDCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::thiscall_t, void> { using type = FUNCTION_SIGNATURE(CC_THISCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::fastcall_t, void> { using type = FUNCTION_SIGNATURE(CC_FASTCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::fastcall_t, types::variadic_t> { using type = FUNCTION_SIGNATURE_VA(CC_FASTCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::vectorcall_t, void> { using type = FUNCTION_SIGNATURE(CC_VECTORCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::regcall_t, void> { using type = FUNCTION_SIGNATURE(CC_REGCALL, RT, A...); }; | ||
|
||
template<typename RT, typename ...A> | ||
struct function_signature<RT(A...), types::regcall_t, types::variadic_t> { 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#pragma once | ||
#include <concepts> | ||
#include <functional> | ||
#include "moar_ptr.h" | ||
|
||
namespace moar | ||
{ | ||
namespace type_traits | ||
{ | ||
/// <summary> | ||
/// Selects T1 or T2 depending on if T1 or T2 is Variadic | ||
/// </summary> | ||
template<concepts::CommonType T1, concepts::CommonType T2> | ||
struct SelectVariadic { | ||
static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectVariadic (T1 and/or T2 missing.)"); | ||
using type = void; | ||
}; | ||
|
||
template<concepts::CallingConvention T1, concepts::Variadic T2> | ||
struct SelectVariadic<T1, T2> { using type = T2; }; | ||
|
||
template<concepts::Variadic T1, concepts::CallingConvention T2> | ||
struct SelectVariadic<T1, T2> { using type = T1; }; | ||
|
||
/// <summary> | ||
/// Selects T1 or T2 depending on if T1 or T2 is a Calling Convention | ||
/// </summary> | ||
template<concepts::CommonType T1, concepts::CommonType T2> | ||
struct SelectCallingConvention { | ||
static_assert(sizeof(T1) == 0 || sizeof(T2) == 0, "Incorrect Usage of SelectCallingConvention (T1 and/or T2 missing.)"); | ||
using type = void; | ||
}; | ||
|
||
template<concepts::CallingConvention T1, concepts::Variadic T2> | ||
struct SelectCallingConvention<T1, T2> { using type = T1; }; | ||
|
||
template<concepts::Variadic T1, concepts::CallingConvention T2> | ||
struct SelectCallingConvention<T1, T2> { using type = T2; }; | ||
|
||
template<typename T> | ||
struct SelectDefaultT3 { | ||
static_assert(sizeof(T) == 0, "Incorrect Usage of SelectDefaultT3 (T missing.)"); | ||
using type = void; | ||
}; | ||
|
||
template<concepts::Variadic T> | ||
struct SelectDefaultT3<T> { using type = types::default_calling_convention; }; | ||
|
||
template<concepts::CallingConvention T> | ||
struct SelectDefaultT3<T> { using type = types::default_variadic; }; | ||
|
||
} | ||
} |
Oops, something went wrong.