diff --git a/example/calling_convention_cdecl.cpp b/example/calling_convention_cdecl.cpp new file mode 100644 index 0000000..39b98e7 --- /dev/null +++ b/example/calling_convention_cdecl.cpp @@ -0,0 +1,34 @@ +/*!<- +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) +->*/ + +//[ calling_convention_cdecl + +#define CALLABLE_TRAITS_ENABLE_CDECL + +#include +#include +#include + +namespace ct = callable_traits; +namespace cc = callable_traits::calling_conventions; + +struct foo {}; + +int main() { + + 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 test = ct::add_calling_convention; + static_assert(std::is_same::value, ""); + static_assert(ct::has_calling_convention(), ""); +} +//] diff --git a/include/callable_traits/add_calling_convention.hpp b/include/callable_traits/add_calling_convention.hpp new file mode 100644 index 0000000..14ad00c --- /dev/null +++ b/include/callable_traits/add_calling_convention.hpp @@ -0,0 +1,111 @@ +/*! +@file add_function_const + +@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_ADD_CALLING_CONVENTION_HPP +#define CALLABLE_TRAITS_ADD_CALLING_CONVENTION_HPP + +#include +#include + +namespace callable_traits { + + namespace detail { + + template + struct add_calling_convention_error { + + static_assert(Sfinae, + "Unknown calling convention type. Did you use a type " + "from namespace callable_traits::calling_conventions?"); + }; + + template + struct add_calling_convention_error { + + #ifdef CALLABLE_TRAITS_ENABLE_STDCALL + static_assert(Sfinae, + "Unable to add __stdcall to type T in " + "callable_traits::add_calling_convention."); + #else + static_assert(Sfinae, + "__stdcall functionality not enabled. Define " + "CALLABLE_TRAITS_ENABLE_STDCALL to enable."); + #endif + }; + + template + struct add_calling_convention_error { + + #ifdef CALLABLE_TRAITS_ENABLE_FASTCALL + static_assert(Sfinae, + "Unable to add __fastcall to type T in " + "callable_traits::add_calling_convention."); + #else + static_assert(Sfinae, + "__fastcall functionality not enabled. Define " + "CALLABLE_TRAITS_ENABLE_FASTCALL to enable."); + #endif + }; + + template + struct add_calling_convention_error { + + #ifdef CALLABLE_TRAITS_ENABLE_CDECL + static_assert(Sfinae, + "Unable to add __cdecl to type T in " + "callable_traits::add_calling_convention."); + #else + static_assert(Sfinae, + "__cdecl functionality not enabled. Define " + "CALLABLE_TRAITS_ENABLE_CDECL to enable."); + #endif + }; + + template + struct add_calling_convention_error { + +#ifdef CALLABLE_TRAITS_ENABLE_PASCAL + static_assert(Sfinae, + "Unable to add pascal to type T in " + "callable_traits::add_calling_convention."); +#else + static_assert(Sfinae, + "pascal functionality not enabled. Define " + "CALLABLE_TRAITS_ENABLE_PASCAL to enable."); +#endif + }; + } + + namespace permissive { + + template + using add_calling_convention = detail::fallback_if_invalid< + typename detail::add_calling_convention_t::type, + T>; + } + + namespace verbose { + + template + using add_calling_convention = detail::fail_if_invalid< + typename detail::add_calling_convention_t::type, + detail::add_calling_convention_error>; + } + + template + using add_calling_convention = detail::fail_if_invalid< + typename detail::add_calling_convention_t::type, + detail::add_calling_convention_error>; +} + +#endif //CALLABLE_TRAITS_ADD_CALLING_CONVENTION_HPP diff --git a/include/callable_traits/callable_traits.hpp b/include/callable_traits/callable_traits.hpp index afbe772..1b7ee6c 100644 --- a/include/callable_traits/callable_traits.hpp +++ b/include/callable_traits/callable_traits.hpp @@ -44,6 +44,8 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include +#include #include #endif diff --git a/include/callable_traits/detail/calling_conventions.hpp b/include/callable_traits/detail/calling_conventions.hpp new file mode 100644 index 0000000..5f5f878 --- /dev/null +++ b/include/callable_traits/detail/calling_conventions.hpp @@ -0,0 +1,98 @@ +/* +Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +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) + +*/ + +#ifndef CALLABLE_TRAITS_DETAIL_CALLING_CONVENTIONS_HPP +#define CALLABLE_TRAITS_DETAIL_CALLING_CONVENTIONS_HPP + +#include +#include + +namespace callable_traits { + + namespace calling_conventions { + struct cdecl{}; + struct stdcall{}; + struct fastcall{}; + struct pascal{}; + } + + namespace detail { + + template + struct add_calling_convention_t { + using type = invalid_type; + }; + + template + struct has_calling_convention_t { + using type = std::false_type; + }; + + // function pointers + + #ifdef CALLABLE_TRAITS_ENABLE_STDCALL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::stdcall + #define CALLABLE_TRAITS_CC __stdcall + #define CALLABLE_TRAITS_ST + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_ST + #undef CALLABLE_TRAITS_CC_TAG + #endif + + #ifdef CALLABLE_TRAITS_ENABLE_FASTCALL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::fastcall + #define CALLABLE_TRAITS_CC __fastcall + #define CALLABLE_TRAITS_ST + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_ST + #undef CALLABLE_TRAITS_CC_TAG + #endif + + #ifdef CALLABLE_TRAITS_ENABLE_PASCAL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::pascal + #define CALLABLE_TRAITS_CC + #define CALLABLE_TRAITS_ST pascal + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_ST + #undef CALLABLE_TRAITS_CC_TAG + #endif + + // member function pointers + + #ifdef CALLABLE_TRAITS_ENABLE_CDECL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::cdecl + #define CALLABLE_TRAITS_CC __cdecl + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_CC_TAG + #endif + + #ifdef CALLABLE_TRAITS_ENABLE_STDCALL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::stdcall + #define CALLABLE_TRAITS_CC __stdcall + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_CC_TAG + #endif + + #ifdef CALLABLE_TRAITS_ENABLE_FASTCALL + #define CALLABLE_TRAITS_CC_TAG calling_conventions::fastcall + #define CALLABLE_TRAITS_CC __fastcall + #include + #undef CALLABLE_TRAITS_CC + #undef CALLABLE_TRAITS_CC_TAG + #endif + + } +} + +#endif diff --git a/include/callable_traits/detail/function.hpp b/include/callable_traits/detail/function.hpp index e43e3d2..830e675 100644 --- a/include/callable_traits/detail/function.hpp +++ b/include/callable_traits/detail/function.hpp @@ -129,6 +129,7 @@ struct function using apply_return = NewReturn(Args..., ...) QUAL; \ } \ /**/ + namespace callable_traits { namespace detail { diff --git a/include/callable_traits/detail/function_cc.hpp b/include/callable_traits/detail/function_cc.hpp new file mode 100644 index 0000000..e1bc9fd --- /dev/null +++ b/include/callable_traits/detail/function_cc.hpp @@ -0,0 +1,34 @@ +/* +Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +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) + + +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_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; +}; \ No newline at end of file diff --git a/include/callable_traits/detail/pmf_cc.hpp b/include/callable_traits/detail/pmf_cc.hpp new file mode 100644 index 0000000..db25684 --- /dev/null +++ b/include/callable_traits/detail/pmf_cc.hpp @@ -0,0 +1,52 @@ +/* +Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +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) + + +DO NOT INCLUDE THIS HEADER DIRECTLY +*/ + +#define CALLABLE_TRAITS_SPECIALIZE_PMF_CC(QUAL) \ + \ + template \ + struct add_calling_convention_t< \ + Ret(T::*)(Args...) QUAL, CALLABLE_TRAITS_CC_TAG> { \ + using type = Ret(CALLABLE_TRAITS_CC T::*)(Args...); \ + }; \ + \ + template \ + struct add_calling_convention_t< \ + Ret(T::*)(Args..., ...) QUAL, CALLABLE_TRAITS_CC_TAG> { \ + using type = Ret(CALLABLE_TRAITS_CC T::*)(Args..., ...); \ + }; \ + \ + template \ + struct has_calling_convention_t< \ + Ret(CALLABLE_TRAITS_CC T::*)(Args...) QUAL, CALLABLE_TRAITS_CC_TAG> { \ + using type = std::true_type; \ + }; \ + \ + template \ + struct has_calling_convention_t< \ + Ret(CALLABLE_TRAITS_CC T::*)(Args..., ...) QUAL, CALLABLE_TRAITS_CC_TAG> { \ + using type = std::true_type; \ + } \ +/**/ + +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(CALLABLE_TRAITS_EMPTY); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(&); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(&&); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(volatile); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const volatile); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const &); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(volatile &); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const volatile &); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const &&); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(volatile &&); +CALLABLE_TRAITS_SPECIALIZE_PMF_CC(const volatile &&); + +#undef CALLABLE_TRAITS_SPECIALIZE_PMF_CC diff --git a/include/callable_traits/detail/utility.hpp b/include/callable_traits/detail/utility.hpp index 724ee5f..93cf1f0 100644 --- a/include/callable_traits/detail/utility.hpp +++ b/include/callable_traits/detail/utility.hpp @@ -24,6 +24,7 @@ struct constants { struct invalid_type { invalid_type() = delete; }; + namespace detail { // used to convey "this type doesn't matter" in code diff --git a/include/callable_traits/has_calling_convention.hpp b/include/callable_traits/has_calling_convention.hpp new file mode 100644 index 0000000..5cec74f --- /dev/null +++ b/include/callable_traits/has_calling_convention.hpp @@ -0,0 +1,25 @@ +/*! +@file add_function_const + +@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_HAS_CALLING_CONVENTION_HPP +#define CALLABLE_TRAITS_HAS_CALLING_CONVENTION_HPP + +#include +#include + +namespace callable_traits { + + template + inline constexpr auto + has_calling_convention() { + return typename detail::has_calling_convention_t::type{}; + } +} + +#endif //CALLABLE_TRAITS_HAS_CALLING_CONVENTION_HPP diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index ed758b3..c23e8aa 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -7,30 +7,17 @@ Distributed under the Boost Software License, Version 1.0. //[ result_of #include -#include +#define CALLABLE_TRAITS_ENABLE_CDECL +#include namespace ct = callable_traits; -using expect = int; - struct foo; -template -void test() { - using result = ct::result_of; - static_assert(std::is_same{}, ""); -} - int main() { - test(); - test(); - test(); - test(); - test(); - - auto x = []() -> int { return 0; }; - - test(); + using pmf = void(foo::*)(); + using expect = void(__cdecl foo::*)(); + static_assert(!std::is_same::value, ""); } //]