diff --git a/example/apply_member_pointer/example.cpp b/example/apply_member_pointer/example.cpp new file mode 100644 index 0000000..111fa63 --- /dev/null +++ b/example/apply_member_pointer/example.cpp @@ -0,0 +1,32 @@ +/*! +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) +*/ + +#include + +namespace ct = callable_traits; + +struct foo; +struct bar; + +using expect = int(foo::*)(int); + +template +void test() { + using U = ct::apply_member_pointer; + static_assert(std::is_same{}, ""); +} + +int main() { + test(); + test(); + test(); + test(); + test(); + test(); + test(); +} + diff --git a/example/remove_member_pointer/example.cpp b/example/remove_member_pointer/example.cpp new file mode 100644 index 0000000..398bbdd --- /dev/null +++ b/example/remove_member_pointer/example.cpp @@ -0,0 +1,41 @@ +/*! +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) +*/ + +#include + +namespace ct = callable_traits; + +struct foo; + +template +void test() { + using U = ct::remove_member_pointer; + static_assert(std::is_same{}, ""); +} + +int main() { + + { + using T = int(foo::*)(int) const; + using expect = int(int) const; + test(); + } { + using T = int foo::*; + using expect = int; + test(); + } { + using T = int(int); + test(); + } { + using T = int(*)(int); + test(); + } { + using T = int(&)(int); + test(); + } +} + diff --git a/include/callable_traits/detail/function.hpp b/include/callable_traits/detail/function.hpp index 1752d79..6c77f90 100644 --- a/include/callable_traits/detail/function.hpp +++ b/include/callable_traits/detail/function.hpp @@ -71,6 +71,8 @@ struct function template \ using apply_member_pointer = add_member_pointer; \ \ + using remove_member_pointer = type; \ + \ template \ using apply_return = NewReturn(Args...) QUAL; \ \ @@ -124,6 +126,8 @@ struct function using apply_member_pointer = \ Return( CALLABLE_TRAITS_VARARGS_CC U::*)(Args..., ...) QUAL; \ \ + using remove_member_pointer = type; \ + \ template \ using apply_return = NewReturn(Args..., ...) QUAL; \ } \ @@ -174,6 +178,8 @@ namespace callable_traits { template using apply_return = typename base::template apply_return&; + + using remove_member_pointer = type; }; template @@ -197,6 +203,8 @@ namespace callable_traits { template using apply_return = typename base::template apply_return&; + + using remove_member_pointer = type; }; template diff --git a/include/callable_traits/detail/function_object.hpp b/include/callable_traits/detail/function_object.hpp index 7cb924a..17291a2 100644 --- a/include/callable_traits/detail/function_object.hpp +++ b/include/callable_traits/detail/function_object.hpp @@ -95,7 +95,7 @@ namespace callable_traits { using add_varargs = invalid_type; template - using add_member_pointer = invalid_type; + using apply_member_pointer = invalid_type; template using apply_return = invalid_type; diff --git a/include/callable_traits/detail/pmd.hpp b/include/callable_traits/detail/pmd.hpp index 529f9b4..7de6fbf 100644 --- a/include/callable_traits/detail/pmd.hpp +++ b/include/callable_traits/detail/pmd.hpp @@ -59,6 +59,9 @@ namespace callable_traits { using remove_member_pointer = D; + template + using apply_member_pointer = D C::*; + using remove_reference = invalid_type; using add_lvalue_reference = invalid_type; using add_rvalue_reference = invalid_type; diff --git a/include/callable_traits/detail/pmf.hpp b/include/callable_traits/detail/pmf.hpp index 1f04341..a63fba9 100644 --- a/include/callable_traits/detail/pmf.hpp +++ b/include/callable_traits/detail/pmf.hpp @@ -24,7 +24,7 @@ struct pmf \ static constexpr bool value = true; \ using has_varargs = std::false_type; \ - static constexpr bool is_ambiguous = false; \ + using is_ambiguous = std::false_type; \ using is_member_pointer = std::true_type; \ using is_function_object = std::false_type; \ using is_member_function_pointer = std::true_type; \ @@ -72,6 +72,8 @@ struct pmf \ template \ using apply_return = NewReturn(T::*)(Args...) QUAL; \ + \ + using remove_member_pointer = abominable_type; \ }; \ \ template \ @@ -80,7 +82,7 @@ struct pmf \ static constexpr bool value = true; \ using has_varargs = std::true_type; \ - static constexpr bool is_ambiguous = false; \ + using is_ambiguous = std::false_type; \ using is_member_pointer = std::true_type; \ using is_function_object = std::false_type; \ using is_member_function_pointer = std::true_type; \ @@ -133,6 +135,8 @@ struct pmf template \ using apply_return = \ NewReturn(CALLABLE_TRAITS_VARARGS_CC T::*)(Args..., ...) QUAL; \ + \ + using remove_member_pointer = abominable_type; \ } \ /**/ diff --git a/include/callable_traits/detail/qualifiers.hpp b/include/callable_traits/detail/qualifiers.hpp index ea7640d..622b156 100644 --- a/include/callable_traits/detail/qualifiers.hpp +++ b/include/callable_traits/detail/qualifiers.hpp @@ -121,7 +121,7 @@ namespace callable_traits { static constexpr flags q_flags = cv_flags | ref_flags; public: - + using is_unqualified = std::integral_constant; using is_reference_qualified = std::integral_constant; using is_lvalue_reference_qualified = std::integral_constant; using is_rvalue_reference_qualified = std::integral_constant; diff --git a/include/callable_traits/interface.hpp b/include/callable_traits/interface.hpp index 9efd849..2d4c6d9 100644 --- a/include/callable_traits/interface.hpp +++ b/include/callable_traits/interface.hpp @@ -72,6 +72,10 @@ namespace callable_traits { using remove_varargs = typename detail::traits::remove_varargs; + template + using remove_member_pointer = + typename detail::traits::remove_member_pointer; + template using add_const_qualifier = typename detail::traits::add_const; @@ -95,6 +99,14 @@ namespace callable_traits { template using add_varargs = typename detail::traits::add_varargs; + + template + using apply_member_pointer = + typename detail::traits::template apply_member_pointer; + + template + using apply_return = + typename detail::traits::template apply_return; } namespace detail { @@ -139,6 +151,12 @@ namespace callable_traits { template using remove_reference_qualifier = detail::if_valid>; + template + using remove_varargs = detail::if_valid>; + + template + using remove_member_pointer = detail::if_valid>; + template using add_const_qualifier = detail::if_valid>; @@ -157,8 +175,13 @@ namespace callable_traits { template using add_varargs = detail::if_valid>; - template - using remove_varargs = detail::if_valid>; + template + using apply_member_pointer = + detail::if_valid>; + + template + using apply_return = + detail::if_valid>; template inline constexpr auto @@ -209,6 +232,18 @@ namespace callable_traits { return typename detail::traits::has_varargs{}; } + template + inline constexpr auto + has_void_return(T&&) { + return typename std::is_same, void>::type{}; + } + + template + inline constexpr auto + has_void_return() { + return typename std::is_same, void>::type{}; + } + template< std::size_t SearchLimit = constants::arity_search_limit, typename T> inline constexpr auto min_arity(T&&) { diff --git a/qtcreator/main/main.cpp b/qtcreator/main/main.cpp index b9e536f..398bbdd 100644 --- a/qtcreator/main/main.cpp +++ b/qtcreator/main/main.cpp @@ -5,41 +5,37 @@ Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) */ -#include -#include #include namespace ct = callable_traits; -struct Vampire {}; -struct Robot {}; -struct Animal {}; -struct Dog : Animal {}; -struct Poodle : Dog {}; -struct Monster : Poodle, Robot, Vampire {}; +struct foo; -struct foo { - Poodle make_poodle(Vampire&&, Robot, Monster, Dog, Animal) const { - return Poodle{}; +template +void test() { + using U = ct::remove_member_pointer; + static_assert(std::is_same{}, ""); +} + +int main() { + + { + using T = int(foo::*)(int) const; + using expect = int(int) const; + test(); + } { + using T = int foo::*; + using expect = int; + test(); + } { + using T = int(int); + test(); + } { + using T = int(*)(int); + test(); + } { + using T = int(&)(int); + test(); } -}; +} -using A = Dog(*)( const Monster&, Vampire, Robot, Dog, Animal); -using B = Dog(*&)( Monster, Vampire, Robot, Animal, Dog, ...); -using C = Animal(&)( Vampire, Monster, Robot, Dog, const Animal&); -using D = Poodle(foo::*)( Vampire, Robot, Monster, Dog, Animal) const; -using E = Monster( Vampire, Robot, Dog, Monster, Monster) const volatile; - -using test = ct::common_signature; - -using expect = Animal( - Monster, - Monster, - Monster, - Monster, - Monster -); - -static_assert(std::is_same{}, ""); - -int main(){} diff --git a/qtcreator/tests_and_examples/tests_and_examples.pro b/qtcreator/tests_and_examples/tests_and_examples.pro index 4687b24..0d62c1e 100644 --- a/qtcreator/tests_and_examples/tests_and_examples.pro +++ b/qtcreator/tests_and_examples/tests_and_examples.pro @@ -10,3 +10,5 @@ OTHER_FILES += ../../test/*.cpp \ ../../example/args/*.cpp \ ../../example/signature/*.cpp \ ../../example/common_signature/*.cpp \ + ../../example/apply_member_pointer/*.cpp \ + ../../example/remove_member_pointer/.cpp \