diff --git a/doc/callable_traits.qbk b/doc/callable_traits.qbk index 89c0c59..4b15a09 100644 --- a/doc/callable_traits.qbk +++ b/doc/callable_traits.qbk @@ -34,8 +34,8 @@ The complexity of callable types in C++ is extensive: *pointers to member functions *qualified overloads of member functions: `const`, `volatile`, `&`, `&&` *C-style varargs (`...`) -*calling conventions (`__cdecl`, `__stdcall`, `__fastcall`, `pascal`, etc.) -*`noexcept` ([@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html part of the function type system in C++17]) +*calling conventions/attributes (`__cdecl`, `__stdcall`, `__fastcall`, `pascal`, etc.) +*[@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html [^noexcept]] [library_name] provides a comprehensive, uniform, and modern type-level interface for the manipulation and inspection of callable types in C++. By filling the gaps where existing library solutions fall short, [library_name] aims to provide such an exhaustive interface for the features listed above that library writers will *never again* need to specialize templates for callable types. [library_name] eliminates the need for horrific template specializations like these: @@ -48,7 +48,7 @@ Several library solutions exist to manipulate these types, or to abstract away t The use cases for [library_name] are closely related to those of [@http://www.boost.org/doc/libs/1_60_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html function_traits] and [@http://www.boost.org/doc/libs/1_60_0/libs/function_types/doc/html/index.html FunctionTypes]. -[important [library_name] currently offers no interface for the manipulation of calling conventions. Also, no features are currently implemented to account for C++17's `noexcept`. These features are planned for future versions on supported platforms.] +[important The upcoming C++17 ISO standard brings a language change that adds `noexcept` to signatures. Currently, this is not handled in [library_name], but will be in the future for platforms that support it.] [endsect] @@ -110,6 +110,7 @@ The simplest way to use [library_name] is to include the main header file: [library_name] interface is also broken down by trait into individual header files. To use only the traits you need, include one or more of the following headers, listed alphabetically: +[include_header [link callable_traits.ref_add_calling_convention add_calling_convention]] [include_header [link callable_traits.ref_add_function_const add_function_const]] [include_header [link callable_traits.ref_add_function_cv add_function_cv]] [include_header [link callable_traits.ref_add_function_lvalue add_function_lvalue]] @@ -125,6 +126,7 @@ The simplest way to use [library_name] is to include the main header file: [include_header [link callable_traits.ref_can_invoke can_invoke]] [include_header [link callable_traits.ref_can_invoke_constexpr can_invoke_constexpr]] [include_header [link callable_traits.ref_function_type function_type]] +[include_header [link callable_traits.ref_has_calling_convention has_calling_convention]] [include_header [link callable_traits.ref_has_varargs has_varargs]] [include_header [link callable_traits.ref_has_void_return has_void_return]] [include_header [link callable_traits.ref_is_const_qualified is_const_qualified]] @@ -137,6 +139,7 @@ The simplest way to use [library_name] is to include the main header file: [include_header [link callable_traits.ref_max_arity max_arity]] [include_header [link callable_traits.ref_min_arity min_arity]] [include_header [link callable_traits.ref_qualified_function_type qualified_function_type]] +[include_header [link callable_traits.ref_remove_calling_convention remove_calling_convention]] [include_header [link callable_traits.ref_remove_function_const remove_function_const]] [include_header [link callable_traits.ref_remove_function_cv remove_function_cv]] [include_header [link callable_traits.ref_remove_member_pointer remove_member_pointer]] @@ -149,6 +152,17 @@ The simplest way to use [library_name] is to include the main header file: +[section:ref_add_calling_convention add_calling_convention] +TODO +[heading Example - [^__fastcall] to [^__stdcall]] +[import ../example/changing_calling_conventions.cpp] +[changing_calling_conventions] +[heading Example - [^__cdecl]] +[import ../example/calling_convention_cdecl.cpp] +[calling_convention_cdecl] + +[endsect] + [section:ref_add_function_const add_function_const] TODO [heading Example] @@ -266,6 +280,12 @@ TODO [function_type] [endsect] +[section:ref_has_calling_convention has_calling_convention] +TODO +[heading Example - [^__fastcall] to [^__stdcall]] +[changing_calling_conventions] +[endsect] + [section:ref_has_varargs has_varargs] TODO [heading Example] @@ -353,6 +373,12 @@ TODO [qualified_function_type] [endsect] +[section:ref_remove_calling_convention remove_calling_convention] +TODO +[heading Example - [^__fastcall] to [^__stdcall]] +[changing_calling_conventions] +[endsect] + [section:ref_remove_function_const remove_function_const] TODO [heading Example] diff --git a/doc/html/callable_traits/headers.html b/doc/html/callable_traits/headers.html index df3411b..33173ec 100644 --- a/doc/html/callable_traits/headers.html +++ b/doc/html/callable_traits/headers.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -39,6 +39,7 @@ of the following headers, listed alphabetically:

+ #include<callable_traits/add_calling_convention.hpp>
#include<callable_traits/add_function_const.hpp>
#include<callable_traits/add_function_cv.hpp>
#include<callable_traits/add_function_lvalue.hpp>
@@ -54,6 +55,7 @@ #include<callable_traits/can_invoke.hpp>
#include<callable_traits/can_invoke_constexpr.hpp>
#include<callable_traits/function_type.hpp>
+ #include<callable_traits/has_calling_convention.hpp>
#include<callable_traits/has_varargs.hpp>
#include<callable_traits/has_void_return.hpp>
#include<callable_traits/is_const_qualified.hpp>
@@ -66,6 +68,7 @@ #include<callable_traits/max_arity.hpp>
#include<callable_traits/min_arity.hpp>
#include<callable_traits/qualified_function_type.hpp>
+ #include<callable_traits/remove_calling_convention.hpp>
#include<callable_traits/remove_function_const.hpp>
#include<callable_traits/remove_function_cv.hpp>
#include<callable_traits/remove_member_pointer.hpp>
@@ -85,7 +88,7 @@


-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_add_calling_convention.html b/doc/html/callable_traits/ref_add_calling_convention.html new file mode 100644 index 0000000..d366fce --- /dev/null +++ b/doc/html/callable_traits/ref_add_calling_convention.html @@ -0,0 +1,107 @@ + + + +add_calling_convention + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ TODO +

+

+ + Example + - __fastcall to __stdcall +

+
#define CALLABLE_TRAITS_ENABLE_STDCALL
+#define CALLABLE_TRAITS_ENABLE_FASTCALL
+
+#include <type_traits>
+#include <callable_traits/has_calling_convention.hpp>
+#include <callable_traits/add_calling_convention.hpp>
+#include <callable_traits/remove_calling_convention.hpp>
+
+namespace ct = callable_traits;
+
+int main() {
+
+    using f = void(__fastcall *)(int);
+
+    static_assert(ct::has_calling_convention<f, ct::fastcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<f, ct::stdcall_tag>(), "");
+
+    using expect = void(__stdcall *)(int);
+
+    static_assert(ct::has_calling_convention<expect, ct::stdcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<expect, ct::fastcall_tag>(), "");
+
+    using g = ct::remove_calling_convention<f>;
+    using test = ct::add_calling_convention<g, ct::stdcall_tag>;
+
+    static_assert(ct::has_calling_convention<test, ct::stdcall_tag>(), "");
+    static_assert(std::is_same<test, expect>::value, "");
+}
+
+

+ + Example + - __cdecl +

+
#define CALLABLE_TRAITS_ENABLE_CDECL
+
+#include <type_traits>
+#include <callable_traits/has_calling_convention.hpp>
+#include <callable_traits/add_calling_convention.hpp>
+
+namespace ct = callable_traits;
+
+struct foo {};
+
+int main() {
+
+    //depending on your platform, pmf may alrady have an implicit __cdecl
+    using pmf = void(foo::*)();
+    using expect = void(__cdecl foo::*)();
+    using test = ct::add_calling_convention<pmf, ct::cdecl_tag>;
+
+    static_assert(std::is_same<test, expect>::value, "");
+    static_assert(ct::has_calling_convention<expect, ct::cdecl_tag>(), "");
+    static_assert(ct::has_calling_convention<test, ct::cdecl_tag>(), "");
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_add_function_const.html b/doc/html/callable_traits/ref_add_function_const.html index 3fde10e..47f6c60 100644 --- a/doc/html/callable_traits/ref_add_function_const.html +++ b/doc/html/callable_traits/ref_add_function_const.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -89,7 +89,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_function_type.html b/doc/html/callable_traits/ref_function_type.html index 2e49b81..29f799a 100644 --- a/doc/html/callable_traits/ref_function_type.html +++ b/doc/html/callable_traits/ref_function_type.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -85,7 +85,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_has_calling_convention.html b/doc/html/callable_traits/ref_has_calling_convention.html new file mode 100644 index 0000000..3fe0259 --- /dev/null +++ b/doc/html/callable_traits/ref_has_calling_convention.html @@ -0,0 +1,80 @@ + + + +has_calling_convention + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ TODO +

+

+ + Example + - __fastcall to __stdcall +

+
#define CALLABLE_TRAITS_ENABLE_STDCALL
+#define CALLABLE_TRAITS_ENABLE_FASTCALL
+
+#include <type_traits>
+#include <callable_traits/has_calling_convention.hpp>
+#include <callable_traits/add_calling_convention.hpp>
+#include <callable_traits/remove_calling_convention.hpp>
+
+namespace ct = callable_traits;
+
+int main() {
+
+    using f = void(__fastcall *)(int);
+
+    static_assert(ct::has_calling_convention<f, ct::fastcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<f, ct::stdcall_tag>(), "");
+
+    using expect = void(__stdcall *)(int);
+
+    static_assert(ct::has_calling_convention<expect, ct::stdcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<expect, ct::fastcall_tag>(), "");
+
+    using g = ct::remove_calling_convention<f>;
+    using test = ct::add_calling_convention<g, ct::stdcall_tag>;
+
+    static_assert(ct::has_calling_convention<test, ct::stdcall_tag>(), "");
+    static_assert(std::is_same<test, expect>::value, "");
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_has_varargs.html b/doc/html/callable_traits/ref_has_varargs.html index fc1407f..4d2d901 100644 --- a/doc/html/callable_traits/ref_has_varargs.html +++ b/doc/html/callable_traits/ref_has_varargs.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -47,7 +47,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_qualified_function_type.html b/doc/html/callable_traits/ref_qualified_function_type.html index eb02053..e1f5eb0 100644 --- a/doc/html/callable_traits/ref_qualified_function_type.html +++ b/doc/html/callable_traits/ref_qualified_function_type.html @@ -7,7 +7,7 @@ - + @@ -20,7 +20,7 @@

-PrevUpHomeNext +PrevUpHomeNext

@@ -47,7 +47,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/callable_traits/ref_remove_calling_convention.html b/doc/html/callable_traits/ref_remove_calling_convention.html new file mode 100644 index 0000000..d704ce7 --- /dev/null +++ b/doc/html/callable_traits/ref_remove_calling_convention.html @@ -0,0 +1,80 @@ + + + +remove_calling_convention + + + + + + + + + + + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ TODO +

+

+ + Example + - __fastcall to __stdcall +

+
#define CALLABLE_TRAITS_ENABLE_STDCALL
+#define CALLABLE_TRAITS_ENABLE_FASTCALL
+
+#include <type_traits>
+#include <callable_traits/has_calling_convention.hpp>
+#include <callable_traits/add_calling_convention.hpp>
+#include <callable_traits/remove_calling_convention.hpp>
+
+namespace ct = callable_traits;
+
+int main() {
+
+    using f = void(__fastcall *)(int);
+
+    static_assert(ct::has_calling_convention<f, ct::fastcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<f, ct::stdcall_tag>(), "");
+
+    using expect = void(__stdcall *)(int);
+
+    static_assert(ct::has_calling_convention<expect, ct::stdcall_tag>(), "");
+    static_assert(!ct::has_calling_convention<expect, ct::fastcall_tag>(), "");
+
+    using g = ct::remove_calling_convention<f>;
+    using test = ct::add_calling_convention<g, ct::stdcall_tag>;
+
+    static_assert(ct::has_calling_convention<test, ct::stdcall_tag>(), "");
+    static_assert(std::is_same<test, expect>::value, "");
+}
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/callable_traits/ref_remove_function_const.html b/doc/html/callable_traits/ref_remove_function_const.html index 28560cf..6330a65 100644 --- a/doc/html/callable_traits/ref_remove_function_const.html +++ b/doc/html/callable_traits/ref_remove_function_const.html @@ -6,7 +6,7 @@ - + @@ -20,7 +20,7 @@
-PrevUpHomeNext +PrevUpHomeNext

@@ -47,7 +47,7 @@
-PrevUpHomeNext +PrevUpHomeNext
diff --git a/doc/html/index.html b/doc/html/index.html index b892eb0..25dab44 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -45,6 +45,7 @@ std::function sugar
Headers
+
add_calling_convention
add_function_const
add_function_cv
add_function_lvalue
@@ -60,6 +61,7 @@
can_invoke
can_invoke_constexpr
function_type
+
has_calling_convention
has_varargs
has_void_return
is_const_qualified
@@ -72,6 +74,7 @@
max_arity
min_arity
qualified_function_type
+
remove_calling_convention
remove_function_const
remove_function_cv
remove_member_pointer
@@ -253,13 +256,12 @@ C-style varargs (...)
  • - calling conventions (__cdecl, + calling conventions/attributes (__cdecl, __stdcall, __fastcall, pascal, etc.)
  • - noexcept (part - of the function type system in C++17) + noexcept
  • @@ -296,10 +298,9 @@ Important

    - CallableTraits currently offers no interface for the - manipulation of calling conventions. Also, no features are currently implemented - to account for C++17's noexcept. - These features are planned for future versions on supported platforms. + The upcoming C++17 ISO standard brings a language change that adds noexcept to signatures. Currently, this + is not handled in CallableTraits, but will be in the + future for platforms that support it.

    diff --git a/doc/html/standalone_HTML.manifest b/doc/html/standalone_HTML.manifest index fb4ed81..1a4c84c 100644 --- a/doc/html/standalone_HTML.manifest +++ b/doc/html/standalone_HTML.manifest @@ -1,5 +1,6 @@ index.html callable_traits/headers.html +callable_traits/ref_add_calling_convention.html callable_traits/ref_add_function_const.html callable_traits/ref_add_function_cv.html callable_traits/ref_add_function_lvalue.html @@ -15,6 +16,7 @@ callable_traits/ref_bind.html callable_traits/ref_can_invoke.html callable_traits/ref_can_invoke_constexpr.html callable_traits/ref_function_type.html +callable_traits/ref_has_calling_convention.html callable_traits/ref_has_varargs.html callable_traits/ref_has_void_return.html callable_traits/ref_is_const_qualified.html @@ -27,6 +29,7 @@ callable_traits/ref_is_volatile_qualified.html callable_traits/ref_max_arity.html callable_traits/ref_min_arity.html callable_traits/ref_qualified_function_type.html +callable_traits/ref_remove_calling_convention.html callable_traits/ref_remove_function_const.html callable_traits/ref_remove_function_cv.html callable_traits/ref_remove_member_pointer.html diff --git a/example/calling_convention_cdecl.cpp b/example/calling_convention_cdecl.cpp index 1ceb4ba..efccf50 100644 --- a/example/calling_convention_cdecl.cpp +++ b/example/calling_convention_cdecl.cpp @@ -19,15 +19,13 @@ struct foo {}; int main() { + //depending on your platform, pmf may alrady have an implicit __cdecl using pmf = void(foo::*)(); - using pmf_cdecl = void(__cdecl foo::*)(); - - static_assert(!std::is_same::value, ""); - static_assert(!ct::has_calling_convention(), ""); - static_assert(ct::has_calling_convention(), ""); - + using expect = void(__cdecl foo::*)(); using test = ct::add_calling_convention; - static_assert(std::is_same::value, ""); + + static_assert(std::is_same::value, ""); + static_assert(ct::has_calling_convention(), ""); static_assert(ct::has_calling_convention(), ""); } //] diff --git a/example/changing_calling_conventions.cpp b/example/changing_calling_conventions.cpp new file mode 100644 index 0000000..19b3b34 --- /dev/null +++ b/example/changing_calling_conventions.cpp @@ -0,0 +1,37 @@ +/*!<- +Copyright (c) 2016 Barrett Adair + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) +->*/ + +//[ changing_calling_conventions +#define CALLABLE_TRAITS_ENABLE_STDCALL +#define CALLABLE_TRAITS_ENABLE_FASTCALL + +#include +#include +#include +#include + +namespace ct = callable_traits; + +int main() { + + using f = void(__fastcall *)(int); + + static_assert(ct::has_calling_convention(), ""); + static_assert(!ct::has_calling_convention(), ""); + + using expect = void(__stdcall *)(int); + + static_assert(ct::has_calling_convention(), ""); + static_assert(!ct::has_calling_convention(), ""); + + using g = ct::remove_calling_convention; + using test = ct::add_calling_convention; + + static_assert(ct::has_calling_convention(), ""); + static_assert(std::is_same::value, ""); +} +//] diff --git a/include/callable_traits/detail/function.hpp b/include/callable_traits/detail/function.hpp index 72a72be..78e6e2c 100644 --- a/include/callable_traits/detail/function.hpp +++ b/include/callable_traits/detail/function.hpp @@ -160,14 +160,17 @@ namespace callable_traits { #define CALLABLE_TRAITS_CC #define CALLABLE_TRAITS_ST #include + #include #undef CALLABLE_TRAITS_ST #undef CALLABLE_TRAITS_CC #undef CALLABLE_TRAITS_CC_TAG #undef CALLABLE_TRAITS_VARARGS_CC + //todo cdecl - need to split variadic and normal function pointers + #ifdef CALLABLE_TRAITS_ENABLE_STDCALL - #define CALLABLE_TRAITS_CC_TAG calling_conventions::stdcall - #define CALLABLE_TRAITS_VARARGS_CC __stdcall + #define CALLABLE_TRAITS_CC_TAG stdcall_tag + #define CALLABLE_TRAITS_VARARGS_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC #define CALLABLE_TRAITS_CC __stdcall #define CALLABLE_TRAITS_ST #include @@ -178,8 +181,8 @@ namespace callable_traits { #endif #ifdef CALLABLE_TRAITS_ENABLE_FASTCALL - #define CALLABLE_TRAITS_CC_TAG calling_conventions::fastcall - #define CALLABLE_TRAITS_VARARGS_CC __fastcall + #define CALLABLE_TRAITS_CC_TAG fastcall_tag + #define CALLABLE_TRAITS_VARARGS_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC #define CALLABLE_TRAITS_CC __fastcall #define CALLABLE_TRAITS_ST #include @@ -190,7 +193,7 @@ namespace callable_traits { #endif #ifdef CALLABLE_TRAITS_ENABLE_PASCAL - #define CALLABLE_TRAITS_CC_TAG calling_conventions::pascal + #define CALLABLE_TRAITS_CC_TAG pascal_tag #define CALLABLE_TRAITS_VARARGS_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC #define CALLABLE_TRAITS_CC #define CALLABLE_TRAITS_ST pascal diff --git a/include/callable_traits/detail/function_cc.hpp b/include/callable_traits/detail/function_cc.hpp index 6f65a60..26ee1bf 100644 --- a/include/callable_traits/detail/function_cc.hpp +++ b/include/callable_traits/detail/function_cc.hpp @@ -14,24 +14,12 @@ struct add_calling_convention_t< using type = CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_CC*)(Args...); }; -template -struct add_calling_convention_t< - Ret(*)(Args..., ...), CALLABLE_TRAITS_CC_TAG> { - using type = CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_CC*)(Args..., ...); -}; - template struct has_calling_convention_t< CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_CC*)(Args...), CALLABLE_TRAITS_CC_TAG> { using type = std::true_type; }; -template -struct has_calling_convention_t< - CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_CC*)(Args..., ...), CALLABLE_TRAITS_CC_TAG> { - using type = std::true_type; -}; - template struct function : qualifier_traits, default_callable_traits { @@ -67,41 +55,3 @@ struct function CALLABLE_TRAITS_ST NewReturn(CALLABLE_TRAITS_CC *)(Args...); }; -template -struct function - : qualifier_traits, default_callable_traits { - - static constexpr bool value = true; - - using is_function = std::true_type; - using is_functionish = std::true_type; - using has_varargs = std::true_type; - using traits = function; - using return_type = Return; - using arg_types = std::tuple; - using invoke_arg_types = arg_types; - - using remove_calling_convention = - Return(CALLABLE_TRAITS_DEFAULT_VARARGS_CC*)(Args..., ...); - - using type = - CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_VARARGS_CC *)(Args..., ...); - - using function_type = Return(Args..., ...); - using qualified_function_type = function_type; - - using remove_varargs = - CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_CC *)(Args...); - - using add_varargs = type; - using remove_member_pointer = type; - - template - using apply_member_pointer = - CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_VARARGS_CC U::*)(Args..., ...); - - template - using apply_return = - CALLABLE_TRAITS_ST NewReturn(CALLABLE_TRAITS_VARARGS_CC *)(Args..., ...); -}; - diff --git a/include/callable_traits/detail/pmf.hpp b/include/callable_traits/detail/pmf.hpp index 78fd82a..6d82cce 100644 --- a/include/callable_traits/detail/pmf.hpp +++ b/include/callable_traits/detail/pmf.hpp @@ -80,38 +80,22 @@ namespace callable_traits { #ifdef CALLABLE_TRAITS_ENABLE_STDCALL #define CALLABLE_TRAITS_CC_TAG stdcall_tag - #define CALLABLE_TRAITS_VARARGS_CC __stdcall + #define CALLABLE_TRAITS_VARARGS_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC #define CALLABLE_TRAITS_CC __stdcall #include #undef CALLABLE_TRAITS_CC #undef CALLABLE_TRAITS_CC_TAG #undef CALLABLE_TRAITS_VARARGS_CC - - #define CALLABLE_TRAITS_CC_TAG stdcall_tag - #define CALLABLE_TRAITS_VARARGS_CC __stdcall - #define CALLABLE_TRAITS_CC __stdcall - #include - #undef CALLABLE_TRAITS_CC - #undef CALLABLE_TRAITS_CC_TAG - #undef CALLABLE_TRAITS_VARARGS_CC #endif #ifdef CALLABLE_TRAITS_ENABLE_FASTCALL #define CALLABLE_TRAITS_CC_TAG fastcall_tag - #define CALLABLE_TRAITS_VARARGS_CC __fastcall + #define CALLABLE_TRAITS_VARARGS_CC CALLABLE_TRAITS_DEFAULT_VARARGS_CC #define CALLABLE_TRAITS_CC __fastcall #include #undef CALLABLE_TRAITS_CC #undef CALLABLE_TRAITS_CC_TAG #undef CALLABLE_TRAITS_VARARGS_CC - - #define CALLABLE_TRAITS_CC_TAG fastcall_tag - #define CALLABLE_TRAITS_VARARGS_CC __fastcall - #define CALLABLE_TRAITS_CC __fastcall - #include - #undef CALLABLE_TRAITS_CC - #undef CALLABLE_TRAITS_CC_TAG - #undef CALLABLE_TRAITS_VARARGS_CC #endif } } diff --git a/include/callable_traits/detail/varargs_function_cc.hpp b/include/callable_traits/detail/varargs_function_cc.hpp new file mode 100644 index 0000000..9955ad2 --- /dev/null +++ b/include/callable_traits/detail/varargs_function_cc.hpp @@ -0,0 +1,60 @@ +/* +Copyright (c) 2016 Modified Work Barrett Adair + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +HEADER GUARDS INTENTIONALLY OMITTED +DO NOT INCLUDE THIS HEADER DIRECTLY +*/ + +template +struct add_calling_convention_t< + Ret(*)(Args..., ...), CALLABLE_TRAITS_CC_TAG> { + using type = CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_VARARGS_CC*)(Args..., ...); +}; + +template +struct has_calling_convention_t< + CALLABLE_TRAITS_ST Ret(CALLABLE_TRAITS_VARARGS_CC*)(Args..., ...), CALLABLE_TRAITS_CC_TAG> { + using type = std::true_type; +}; + +template +struct function + : qualifier_traits, default_callable_traits { + + static constexpr bool value = true; + + using is_function = std::true_type; + using is_functionish = std::true_type; + using has_varargs = std::true_type; + using traits = function; + using return_type = Return; + using arg_types = std::tuple; + using invoke_arg_types = arg_types; + + using remove_calling_convention = + Return(CALLABLE_TRAITS_DEFAULT_VARARGS_CC*)(Args..., ...); + + using type = + CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_VARARGS_CC *)(Args..., ...); + + using function_type = Return(Args..., ...); + using qualified_function_type = function_type; + + using remove_varargs = + CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_CC *)(Args...); + + using add_varargs = type; + using remove_member_pointer = type; + + template + using apply_member_pointer = + CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_VARARGS_CC U::*)(Args..., ...); + + template + using apply_return = + CALLABLE_TRAITS_ST NewReturn(CALLABLE_TRAITS_VARARGS_CC *)(Args..., ...); +}; + diff --git a/include/callable_traits/remove_calling_convention.hpp b/include/callable_traits/remove_calling_convention.hpp new file mode 100644 index 0000000..bf7e4a8 --- /dev/null +++ b/include/callable_traits/remove_calling_convention.hpp @@ -0,0 +1,49 @@ +/* +@copyright Barrett Adair 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + +*/ + +#ifndef CALLABLE_TRAITS_REMOVE_CALLING_CONVENTION_HPP +#define CALLABLE_TRAITS_REMOVE_CALLING_CONVENTION_HPP + +#include +#include + +namespace callable_traits { + + namespace detail { + + template + struct remove_calling_convention_error { + + static_assert(Sfinae, + "Unable to remove calling convention from type T in" + "callable_traits::remove_calling_convention."); + }; + } + + namespace permissive { + + template + using remove_calling_convention = detail::fallback_if_invalid< + typename detail::traits::remove_calling_convention, + T>; + } + + namespace verbose { + + template + using remove_calling_convention = detail::fail_if_invalid< + typename detail::traits::remove_calling_convention, + detail::remove_calling_convention_error>; + } + + template + using remove_calling_convention = detail::fail_if_invalid< + typename detail::traits::remove_calling_convention, + detail::remove_calling_convention_error>; +} + +#endif //CALLABLE_TRAITS_REMOVE_CALLING_CONVENTION_HPP diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index 1ceb4ba..6b55b38 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -7,11 +7,13 @@ Distributed under the Boost Software License, Version 1.0. //[ calling_convention_cdecl -#define CALLABLE_TRAITS_ENABLE_CDECL +#define CALLABLE_TRAITS_ENABLE_STDCALL +#define CALLABLE_TRAITS_ENABLE_FASTCALL #include #include #include +#include namespace ct = callable_traits; @@ -19,15 +21,20 @@ struct foo {}; int main() { - using pmf = void(foo::*)(); - using pmf_cdecl = void(__cdecl foo::*)(); + using f = void(__fastcall *)(int); - static_assert(!std::is_same::value, ""); - static_assert(!ct::has_calling_convention(), ""); - static_assert(ct::has_calling_convention(), ""); + static_assert(ct::has_calling_convention(), ""); + static_assert(!ct::has_calling_convention(), ""); - using test = ct::add_calling_convention; - static_assert(std::is_same::value, ""); - static_assert(ct::has_calling_convention(), ""); + using expect = void(__stdcall *)(int); + + static_assert(ct::has_calling_convention(), ""); + static_assert(!ct::has_calling_convention(), ""); + + using g = ct::remove_calling_convention; + using test = ct::add_calling_convention; + + static_assert(ct::has_calling_convention(), ""); + static_assert(std::is_same::value, ""); } //]