From 649729920694a6ae49f5463cd65d6ea6d860d4e1 Mon Sep 17 00:00:00 2001 From: badair Date: Fri, 29 Apr 2016 03:51:24 -0500 Subject: [PATCH] tentatively adding more features --- include/callable_traits/args.hpp | 8 +-- include/callable_traits/callable_traits.hpp | 6 +++ include/callable_traits/copy_qualifiers.hpp | 51 ++++++++++++++++++ .../detail/bind_expression_traits.hpp | 4 ++ .../detail/copy_qualifiers_impl.hpp | 38 +++++++++++++ .../detail/default_callable_traits.hpp | 9 ++-- include/callable_traits/detail/qualifiers.hpp | 6 +-- .../detail/set_function_qualifiers.hpp | 24 +++++++-- .../detail/unguarded/function.hpp | 8 ++- .../detail/unguarded/function_ptr.hpp | 1 - .../detail/unguarded/function_ptr_varargs.hpp | 4 +- .../detail/unguarded/pmf_2.hpp | 3 ++ .../detail/unguarded/pmf_varargs_2.hpp | 3 ++ include/callable_traits/detail/utility.hpp | 13 +++-- .../callable_traits/expand_invoke_args.hpp | 48 +++++++++++++++++ .../callable_traits/has_same_qualifiers.hpp | 33 ++++++++++++ include/callable_traits/invoke_args.hpp | 53 +++++++++++++++++++ include/callable_traits/parent_class_of.hpp | 50 +++++++++++++++++ .../qualified_parent_class_of.hpp | 50 +++++++++++++++++ 19 files changed, 385 insertions(+), 27 deletions(-) create mode 100644 include/callable_traits/copy_qualifiers.hpp create mode 100644 include/callable_traits/detail/copy_qualifiers_impl.hpp create mode 100644 include/callable_traits/expand_invoke_args.hpp create mode 100644 include/callable_traits/has_same_qualifiers.hpp create mode 100644 include/callable_traits/invoke_args.hpp create mode 100644 include/callable_traits/parent_class_of.hpp create mode 100644 include/callable_traits/qualified_parent_class_of.hpp diff --git a/include/callable_traits/args.hpp b/include/callable_traits/args.hpp index b4458dc..ce73926 100644 --- a/include/callable_traits/args.hpp +++ b/include/callable_traits/args.hpp @@ -20,17 +20,17 @@ namespace callable_traits { struct args_error { static_assert(Sfinae, - "Could not determine the arguments for " + "Could not determine the parameters for " "T in callable_traits::args. Note: " "If T is the type of a generic lambda or " " overloaded/templated function object, " - "the arguments cannot be determined. "); + "the parameters cannot be determined. "); }; } namespace permissive { - // returns callable_traits::invalid_type if argument types + // returns callable_traits::invalid_type if parameter types // cannot be determined template using args = typename detail::traits::arg_types; @@ -50,4 +50,4 @@ namespace callable_traits { detail::args_error>; } -#endif +#endif //#ifndef CALLABLE_TRAITS_ARGS_HPP diff --git a/include/callable_traits/callable_traits.hpp b/include/callable_traits/callable_traits.hpp index b1c8a39..1ba026e 100644 --- a/include/callable_traits/callable_traits.hpp +++ b/include/callable_traits/callable_traits.hpp @@ -22,15 +22,19 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include #include #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -43,6 +47,8 @@ Distributed under the Boost Software License, Version 1.0. #include #include #include +#include +#include #include #include #include diff --git a/include/callable_traits/copy_qualifiers.hpp b/include/callable_traits/copy_qualifiers.hpp new file mode 100644 index 0000000..e117c65 --- /dev/null +++ b/include/callable_traits/copy_qualifiers.hpp @@ -0,0 +1,51 @@ +/*! +@file + +@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_COPY_QUALIFIERS_HPP +#define CALLABLE_TRAITS_COPY_QUALIFIERS_HPP + +#include +#include + +namespace callable_traits { + + namespace detail { + + template + struct copy_qualifiers_error { + + static_assert(Sfinae, + "TODO: error message for callable_traits::copy_qualifiers"); + }; + } + + namespace permissive { + + // returns callable_traits::invalid_type if parameter types + // cannot be determined + template + using copy_qualifiers = + typename detail::copy_qualifiers_impl, detail::traits>::type; + } + + namespace verbose { + + template + using copy_qualifiers = detail::fail_if_invalid< + typename detail::copy_qualifiers_impl, detail::traits>::type, + detail::invoke_args_error>; + } + + template + using copy_qualifiers = detail::fail_if_invalid< + typename detail::copy_qualifiers_impl, detail::traits>::type, + detail::invoke_args_error>; +} + +#endif //#ifndef CALLABLE_TRAITS_COPY_QUALIFIERS_HPP diff --git a/include/callable_traits/detail/bind_expression_traits.hpp b/include/callable_traits/detail/bind_expression_traits.hpp index d63a2dc..a37249d 100644 --- a/include/callable_traits/detail/bind_expression_traits.hpp +++ b/include/callable_traits/detail/bind_expression_traits.hpp @@ -43,6 +43,10 @@ namespace callable_traits { template class Container> using expand_args = typename bind_expr_detail::expand_bind_args::type; + + template class Container> + using expand_invoke_args = + typename bind_expr_detail::expand_bind_args::type; }; } } diff --git a/include/callable_traits/detail/copy_qualifiers_impl.hpp b/include/callable_traits/detail/copy_qualifiers_impl.hpp new file mode 100644 index 0000000..79fd1a8 --- /dev/null +++ b/include/callable_traits/detail/copy_qualifiers_impl.hpp @@ -0,0 +1,38 @@ +/*! +@file + +@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_DETAIL_COPY_QUALIFIERS_IMPL_HPP +#define CALLABLE_TRAITS_DETAIL_COPY_QUALIFIERS_IMPL_HPP + +#include + +namespace callable_traits { + + namespace detail { + + template::value + && can_accept_member_qualifiers::value> + struct copy_qualifiers_impl; + + template + struct copy_qualifiers_impl { + + using type = typename ToTraits::template set_qualifiers; + }; + + template + struct copy_qualifiers_impl { + + using type = set_other_qualifiers; + }; + } +} + +#endif //#ifndef CALLABLE_TRAITS_DETAIL_COPY_QUALIFIERS_IMPL_HPP diff --git a/include/callable_traits/detail/default_callable_traits.hpp b/include/callable_traits/detail/default_callable_traits.hpp index f6ac8f8..f254b12 100644 --- a/include/callable_traits/detail/default_callable_traits.hpp +++ b/include/callable_traits/detail/default_callable_traits.hpp @@ -52,13 +52,9 @@ namespace callable_traits { // std::true_type for plain function types only using is_function = std::false_type; - // std::true_type for plain function types with qualifiers + // std::true_type for function types with qualifiers using has_member_qualifiers_function = std::false_type; - // std::true_type for function pointers, function references - // and plain function types - using is_functionish = std::false_type; - // std::true_type for callables with C-style variadics using has_varargs = std::false_type; @@ -159,6 +155,9 @@ namespace callable_traits { template class Container> using expand_args = invalid_type; + template class Container> + using expand_invoke_args = invalid_type; + using clear_args = invalid_type; template diff --git a/include/callable_traits/detail/qualifiers.hpp b/include/callable_traits/detail/qualifiers.hpp index 51e4e9d..b73db23 100644 --- a/include/callable_traits/detail/qualifiers.hpp +++ b/include/callable_traits/detail/qualifiers.hpp @@ -133,16 +133,12 @@ namespace callable_traits { template<> struct flag_map { static constexpr flags value = const_ | volatile_ | rref_; }; template - class qualifier_traits { - - protected: + struct qualifier_traits { static constexpr flags cv_flags = cv_of::value; static constexpr flags ref_flags = ref_of::value; static constexpr flags q_flags = cv_flags | ref_flags; - public: - using has_member_qualifiers = std::integral_constant; using is_const_member = std::integral_constant; using is_volatile_member = std::integral_constant; diff --git a/include/callable_traits/detail/set_function_qualifiers.hpp b/include/callable_traits/detail/set_function_qualifiers.hpp index 19a89ef..7d899a4 100644 --- a/include/callable_traits/detail/set_function_qualifiers.hpp +++ b/include/callable_traits/detail/set_function_qualifiers.hpp @@ -16,16 +16,23 @@ Distributed under the Boost Software License, Version 1.0. #define CALLABLE_TRAITS_SET_FUNCTION_QUALIFIERS(QUAL) \ template \ struct set_function_qualifiers_t < \ - flag_map::value, Return, Args... \ -> { \ + flag_map::value, Return, Args...> { \ + \ using type = Return(Args...) QUAL; \ }; \ \ template \ struct set_varargs_function_qualifiers_t < \ - flag_map::value, Return, Args... \ -> { \ + flag_map::value, Return, Args...> { \ + \ using type = Return(Args..., ...) QUAL; \ +}; \ + \ +template \ +struct set_other_qualifiers_t < \ + flag_map::value, T> { \ + \ + using type = T QUAL; \ } \ /**/ @@ -43,6 +50,11 @@ namespace callable_traits { using type = Return(Args..., ...); }; + template + struct set_other_qualifiers_t { + using type = T; + }; + #ifndef CALLABLE_TRAITS_DISABLE_ABOMINABLE_FUNCTIONS CALLABLE_TRAITS_SET_FUNCTION_QUALIFIERS(const); @@ -70,6 +82,10 @@ namespace callable_traits { template using set_varargs_function_qualifiers = typename set_varargs_function_qualifiers_t::type; + + template + using set_other_qualifiers = + typename set_other_qualifiers_t::type; } } diff --git a/include/callable_traits/detail/unguarded/function.hpp b/include/callable_traits/detail/unguarded/function.hpp index b66ea42..77554e1 100644 --- a/include/callable_traits/detail/unguarded/function.hpp +++ b/include/callable_traits/detail/unguarded/function.hpp @@ -16,7 +16,6 @@ struct function static constexpr bool value = true; using is_function = std::true_type; - using is_functionish = std::true_type; using traits = function; using return_type = Return; using arg_types = std::tuple; @@ -66,6 +65,9 @@ struct function template class Container> using expand_args = Container; + template class Container> + using expand_invoke_args = Container; + using clear_args = Return() CALLABLE_TRAITS_INCLUDE_QUALIFIERS; #undef CALLABLE_TRAITS_BEGIN_PACK_MANIP @@ -89,7 +91,6 @@ struct function using has_varargs = std::true_type; using is_function = std::true_type; - using is_functionish = std::true_type; using traits = function; using return_type = Return; using arg_types = std::tuple; @@ -137,6 +138,9 @@ struct function template class Container> using expand_args = Container; + template class Container> + using expand_invoke_args = Container; + using clear_args = Return() CALLABLE_TRAITS_INCLUDE_QUALIFIERS; #define CALLABLE_TRAITS_BEGIN_PACK_MANIP Return( diff --git a/include/callable_traits/detail/unguarded/function_ptr.hpp b/include/callable_traits/detail/unguarded/function_ptr.hpp index bae15e7..936bd33 100644 --- a/include/callable_traits/detail/unguarded/function_ptr.hpp +++ b/include/callable_traits/detail/unguarded/function_ptr.hpp @@ -27,7 +27,6 @@ struct function; diff --git a/include/callable_traits/detail/unguarded/function_ptr_varargs.hpp b/include/callable_traits/detail/unguarded/function_ptr_varargs.hpp index 351c863..8d0eae4 100644 --- a/include/callable_traits/detail/unguarded/function_ptr_varargs.hpp +++ b/include/callable_traits/detail/unguarded/function_ptr_varargs.hpp @@ -27,7 +27,6 @@ struct function class Container> using expand_args = Container; + template class Container> + using expand_invoke_args = Container; + using clear_args = typename copy_cvr< CALLABLE_TRAITS_ST Return(CALLABLE_TRAITS_VARARGS_CC *)(), OriginalType diff --git a/include/callable_traits/detail/unguarded/pmf_2.hpp b/include/callable_traits/detail/unguarded/pmf_2.hpp index 8c9fa45..be25aa9 100644 --- a/include/callable_traits/detail/unguarded/pmf_2.hpp +++ b/include/callable_traits/detail/unguarded/pmf_2.hpp @@ -105,6 +105,9 @@ struct pmf class Container> using expand_args = Container; + template class Container> + using expand_invoke_args = Container; + #undef CALLABLE_TRAITS_BEGIN_PACK_MANIP #undef CALLABLE_TRAITS_ARGS_PACK #undef CALLABLE_TRAITS_END_PACK_MANIP diff --git a/include/callable_traits/detail/unguarded/pmf_varargs_2.hpp b/include/callable_traits/detail/unguarded/pmf_varargs_2.hpp index f6e9598..bf29c81 100644 --- a/include/callable_traits/detail/unguarded/pmf_varargs_2.hpp +++ b/include/callable_traits/detail/unguarded/pmf_varargs_2.hpp @@ -109,6 +109,9 @@ struct pmf class Container> using expand_args = Container; + template class Container> + using expand_invoke_args = Container; + using clear_args = typename copy_cvr< Return(CALLABLE_TRAITS_VARARGS_CC T::*)() CALLABLE_TRAITS_INCLUDE_QUALIFIERS, OriginalType diff --git a/include/callable_traits/detail/utility.hpp b/include/callable_traits/detail/utility.hpp index 8cba2a8..9302c91 100644 --- a/include/callable_traits/detail/utility.hpp +++ b/include/callable_traits/detail/utility.hpp @@ -18,11 +18,11 @@ Distributed under the Boost Software License, Version 1.0. namespace callable_traits { -struct constants { - static constexpr std::size_t arity_search_limit = CALLABLE_TRAITS_ARITY_SEARCH_LIMIT; -}; + struct constants { + static constexpr std::size_t arity_search_limit = CALLABLE_TRAITS_ARITY_SEARCH_LIMIT; + }; -struct invalid_type { invalid_type() = delete; }; + struct invalid_type { invalid_type() = delete; }; namespace detail { @@ -131,7 +131,10 @@ struct invalid_type { invalid_type() = delete; }; template using add_member_pointer = T Class::*; - + template + using can_accept_member_qualifiers = std::integral_constant; + namespace util_detail { template diff --git a/include/callable_traits/expand_invoke_args.hpp b/include/callable_traits/expand_invoke_args.hpp new file mode 100644 index 0000000..e30ea6f --- /dev/null +++ b/include/callable_traits/expand_invoke_args.hpp @@ -0,0 +1,48 @@ +/*! +@file + +@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_EXPAND_INVOKE_ARGS_HPP +#define CALLABLE_TRAITS_EXPAND_INVOKE_ARGS_HPP + +#include + +namespace callable_traits { + + namespace detail { + + template + struct expand_invoke_args_error { + + static_assert(Sfinae, + "callable_traits::expand_invoke_args is not a valid operation."); + }; + } + + namespace permissive { + + // returns callable_traits::invalid_type if argument types cannot be determined + template class Container> + using expand_invoke_args = typename detail::traits::template expand_invoke_args; + } + + namespace verbose { + + template class Container> + using expand_invoke_args = detail::fail_if_invalid< + typename detail::traits::template expand_invoke_args, + detail::expand_invoke_args_error>; + } + + template class Container> + using expand_invoke_args = detail::fail_if_invalid< + typename detail::traits::template expand_invoke_args, + detail::expand_invoke_args_error>; +} + +#endif //#ifndef CALLABLE_TRAITS_EXPAND_INVOKE_ARGS_HPP diff --git a/include/callable_traits/has_same_qualifiers.hpp b/include/callable_traits/has_same_qualifiers.hpp new file mode 100644 index 0000000..45aa44e --- /dev/null +++ b/include/callable_traits/has_same_qualifiers.hpp @@ -0,0 +1,33 @@ +/*! +@file + +@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_SAME_QUALIFIERS_HPP +#define CALLABLE_TRAITS_HAS_SAME_QUALIFIERS_HPP + +#include +#include + +namespace callable_traits { + + + template + inline constexpr auto + has_same_qualifiers() { + return typename std::is_same>::type{}; + } + + template + inline constexpr auto + has_same_qualifiers(T&&, Callable&&) { + return has_same_qualifiers(); + } + +} + +#endif //#ifndef CALLABLE_TRAITS_COPY_QUALIFIERS_HPP diff --git a/include/callable_traits/invoke_args.hpp b/include/callable_traits/invoke_args.hpp new file mode 100644 index 0000000..8883a4f --- /dev/null +++ b/include/callable_traits/invoke_args.hpp @@ -0,0 +1,53 @@ +/*! +@file + +@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_INVOKE_ARGS_HPP +#define CALLABLE_TRAITS_INVOKE_ARGS_HPP + +#include + +namespace callable_traits { + + namespace detail { + + template + struct invoke_args_error { + + static_assert(Sfinae, + "Could not determine the parameters for " + "T in callable_traits::args. Note: " + "If T is the type of a generic lambda or " + " overloaded/templated function object, " + "the parameters cannot be determined. "); + }; + } + + namespace permissive { + + // returns callable_traits::invalid_type if parameter types + // cannot be determined + template + using invoke_args = typename detail::traits::invoke_arg_types; + } + + namespace verbose { + + template + using invoke_args = detail::fail_if_invalid< + typename detail::traits::invoke_arg_types, + detail::invoke_args_error>; + } + + template + using invoke_args = detail::fail_if_invalid< + typename detail::traits::invoke_arg_types, + detail::invoke_args_error>; +} + +#endif //#ifndef CALLABLE_TRAITS_INVOKE_ARGS_HPP diff --git a/include/callable_traits/parent_class_of.hpp b/include/callable_traits/parent_class_of.hpp new file mode 100644 index 0000000..952734b --- /dev/null +++ b/include/callable_traits/parent_class_of.hpp @@ -0,0 +1,50 @@ +/*! +@file + +@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_PARENT_CLASS_OF_HPP +#define CALLABLE_TRAITS_PARENT_CLASS_OF_HPP + +#include + +namespace callable_traits { + + namespace detail { + + template + struct parent_class_of_error { + + static_assert(Sfinae, + "TODO: error message for callable_traits::parent_class_of"); + }; + } + + namespace permissive { + + // returns callable_traits::invalid_type if parameter types + // cannot be determined + template + using parent_class_of = + typename detail::traits::class_type; + } + + namespace verbose { + + template + using parent_class_of = detail::fail_if_invalid< + typename detail::traits::class_type, + detail::invoke_args_error>; + } + + template + using parent_class_of = detail::fail_if_invalid< + typename detail::traits::class_type, + detail::invoke_args_error>; +} + +#endif //#ifndef CALLABLE_TRAITS_PARENT_CLASS_OF_HPP diff --git a/include/callable_traits/qualified_parent_class_of.hpp b/include/callable_traits/qualified_parent_class_of.hpp new file mode 100644 index 0000000..e65bd1a --- /dev/null +++ b/include/callable_traits/qualified_parent_class_of.hpp @@ -0,0 +1,50 @@ +/*! +@file + +@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_QUALIFIED_PARENT_CLASS_OF_HPP +#define CALLABLE_TRAITS_QUALIFIED_PARENT_CLASS_OF_HPP + +#include + +namespace callable_traits { + + namespace detail { + + template + struct qualified_parent_class_of_error { + + static_assert(Sfinae, + "TODO: error message for callable_traits::qualified_parent_class_of"); + }; + } + + namespace permissive { + + // returns callable_traits::invalid_type if parameter types + // cannot be determined + template + using qualified_parent_class_of = + typename detail::traits::invoke_type; + } + + namespace verbose { + + template + using qualified_parent_class_of = detail::fail_if_invalid< + typename detail::traits::invoke_type, + detail::invoke_args_error>; + } + + template + using qualified_parent_class_of = detail::fail_if_invalid< + typename detail::traits::invoke_type, + detail::invoke_args_error>; +} + +#endif //#ifndef CALLABLE_TRAITS_QUALIFIED_PARENT_CLASS_OF_HPP