mirror of
https://github.com/boostorg/callable_traits.git
synced 2026-02-20 02:32:13 +00:00
code cleanup minutia
This commit is contained in:
@@ -27,9 +27,11 @@ namespace callable_traits {
|
||||
any_arg() = default;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
//MSVC doesn't like this because it can deduce 'void'
|
||||
template<typename... T>
|
||||
any_arg(T&&...);
|
||||
#endif //!defined(_MSC_VER)
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,9 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef CALLABLE_TRAITS_ARITY_HPP
|
||||
#define CALLABLE_TRAITS_ARITY_HPP
|
||||
|
||||
#include <callable_traits/test_invoke.hpp>
|
||||
#include <callable_traits/substitution.hpp>
|
||||
#include <callable_traits/disjunction.hpp>
|
||||
#include <callable_traits/can_invoke_t.hpp>
|
||||
#include <callable_traits/any_arg.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -19,6 +20,68 @@ namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Dispatch, typename... Args>
|
||||
struct can_invoke_t {
|
||||
|
||||
using callable = typename Dispatch::type;
|
||||
using class_type = typename Dispatch::class_type;
|
||||
using is_member_pointer = typename Dispatch::is_member_pointer;
|
||||
|
||||
using invoker = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
test_invoke<Dispatch, class_type, Args...>,
|
||||
test_invoke<Dispatch, Args...>
|
||||
>::type;
|
||||
|
||||
using test = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<typename Dispatch::invoke_type>(),
|
||||
std::declval<Args>()...
|
||||
)),
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<Args>()...
|
||||
))
|
||||
>::type;
|
||||
|
||||
static constexpr bool value =
|
||||
!std::is_same<substitution_failure, test>{};
|
||||
|
||||
static constexpr int arg_count = invoker::arg_count;
|
||||
};
|
||||
|
||||
template<typename Dispatch>
|
||||
struct can_invoke_t<Dispatch, void> {
|
||||
|
||||
using callable = typename Dispatch::type;
|
||||
using class_type = typename Dispatch::class_type;
|
||||
using is_member_pointer = typename Dispatch::is_member_pointer;
|
||||
|
||||
using invoker = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
test_invoke<Dispatch>,
|
||||
test_invoke<Dispatch, class_type>
|
||||
>::type;
|
||||
|
||||
using invoke_type = typename Dispatch::invoke_type;
|
||||
|
||||
using test = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<invoke_type>()
|
||||
)),
|
||||
decltype(invoker{}(std::declval<callable>()))
|
||||
>::type;
|
||||
|
||||
static constexpr bool value =
|
||||
!std::is_same<substitution_failure, test>::value;
|
||||
|
||||
static constexpr int arg_count = 0;
|
||||
};
|
||||
|
||||
template<typename, typename>
|
||||
struct max_args {
|
||||
static constexpr bool value = true;
|
||||
|
||||
@@ -8,7 +8,8 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef CALLABLE_TRAITS_BEST_MATCH_HPP
|
||||
#define CALLABLE_TRAITS_BEST_MATCH_HPP
|
||||
|
||||
#include <callable_traits/sort_tuple.hpp>
|
||||
#include <callable_traits/tuple_sort.hpp>
|
||||
#include <callable_traits/prepend.hpp>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -107,7 +108,7 @@ namespace callable_traits {
|
||||
};
|
||||
|
||||
template<typename... Ts>
|
||||
using sorted_cartesian_product_of_conversions = sort_tuple<
|
||||
using sorted_cartesian_product_of_conversions = tuple_sort<
|
||||
std::tuple<map_conversions<Ts, Ts...>...>,
|
||||
conversion_result_sort_predicate
|
||||
>;
|
||||
|
||||
@@ -14,10 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#include <callable_traits/traits.hpp>
|
||||
#include <callable_traits/categorize_bind_arg.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
#include <callable_traits/ph.hpp>
|
||||
#include <callable_traits/sort_tuple.hpp>
|
||||
#include <callable_traits/placeholder_routes.hpp>
|
||||
#include <callable_traits/remove_duplicate_placeholders.hpp>
|
||||
#include <callable_traits/placeholder.hpp>
|
||||
#include <callable_traits/fwd/bind_expression_fwd.hpp>
|
||||
#include <callable_traits/prepend.hpp>
|
||||
//#include <callable_traits/private_tuple.hpp>
|
||||
@@ -35,34 +32,6 @@ namespace callable_traits {
|
||||
PhRouteLeft::ph_value < PhRouteRight::ph_value;
|
||||
};
|
||||
|
||||
template <typename PhRoutesTuple, typename OriginalArgsTuple, typename Seq>
|
||||
struct placeholders_mapped_to_original_signature;
|
||||
|
||||
template <typename PhRoutesTuple, typename OriginalArgsTuple, std::size_t... I>
|
||||
struct placeholders_mapped_to_original_signature<
|
||||
PhRoutesTuple, OriginalArgsTuple, std::index_sequence<I...>> {
|
||||
|
||||
//this is where the magic happens
|
||||
using type = std::tuple<
|
||||
typename std::tuple_element<
|
||||
std::tuple_element<I, PhRoutesTuple>::type::original_arg_index,
|
||||
OriginalArgsTuple
|
||||
>::type...
|
||||
>;
|
||||
};
|
||||
|
||||
template <typename PhRoutesTuple, std::size_t... I>
|
||||
struct placeholders_mapped_to_original_signature<
|
||||
PhRoutesTuple, std::tuple<>, std::index_sequence<I...>> {
|
||||
using type = std::tuple<>;
|
||||
};
|
||||
|
||||
template <typename T, std::size_t... I>
|
||||
struct placeholders_mapped_to_original_signature<
|
||||
T, std::tuple<unknown>, std::index_sequence<I...>> {
|
||||
using type = std::tuple<unknown>;
|
||||
};
|
||||
|
||||
template <typename...> struct bind_expressions_filter;
|
||||
|
||||
template <> struct bind_expressions_filter<> { using type = std::tuple<>; };
|
||||
@@ -152,10 +121,6 @@ namespace callable_traits {
|
||||
using inner_bind_expressions =
|
||||
typename remove_non_bind_expressions<Args...>::type;
|
||||
|
||||
using has_inner_bind_expressions = std::is_same<
|
||||
inner_bind_expressions, std::tuple<>
|
||||
>;
|
||||
|
||||
using flattened_bind_expressions =
|
||||
typename flatten_bind_expressions<bind_expression>::type;
|
||||
|
||||
@@ -164,26 +129,7 @@ namespace callable_traits {
|
||||
bind_args_tuple
|
||||
>::type;
|
||||
|
||||
using sorted_placeholder_routes =
|
||||
typename remove_duplicate_placeholders<
|
||||
sort_tuple<
|
||||
placeholder_route_map,
|
||||
compare_ph_value
|
||||
>
|
||||
>::type;
|
||||
|
||||
using placeholder_count = std::tuple_size<
|
||||
sorted_placeholder_routes
|
||||
>;
|
||||
|
||||
using original_args = typename traits<Callable>::arg_types;
|
||||
|
||||
/*using arg_types = typename placeholders_mapped_to_original_signature<
|
||||
sorted_placeholder_routes,
|
||||
original_args,
|
||||
std::make_index_sequence<placeholder_count::value>
|
||||
>::type;*/
|
||||
|
||||
using return_type = typename traits<Callable>::return_type;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,10 +10,11 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
#include <callable_traits/traits.hpp>
|
||||
#include <callable_traits/tuple_group_by.hpp>
|
||||
#include <callable_traits/sort_tuple.hpp>
|
||||
#include <callable_traits/tuple_sort.hpp>
|
||||
#include <callable_traits/bind_expression.hpp>
|
||||
#include <callable_traits/fwd/bind_expression_parser_fwd.hpp>
|
||||
#include <callable_traits/best_match.hpp>
|
||||
#include <callable_traits/prepend.hpp>
|
||||
#include <tuple>
|
||||
#include <functional>
|
||||
|
||||
@@ -33,7 +34,7 @@ namespace callable_traits {
|
||||
typename BindExprs::bind_args_tuple
|
||||
>::type>()...));
|
||||
|
||||
using type = sort_tuple<
|
||||
using type = tuple_sort<
|
||||
placeholder_route_map,
|
||||
compare_ph_value
|
||||
>;
|
||||
|
||||
@@ -22,30 +22,38 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#include <callable_traits/pmf.hpp>
|
||||
#include <callable_traits/function.hpp>
|
||||
#include <callable_traits/function_object.hpp>
|
||||
#include <callable_traits/general.hpp>
|
||||
#include <callable_traits/remove_reference_if_ptr.hpp>
|
||||
#include <callable_traits/default_dispatch.hpp>
|
||||
#include <callable_traits/can_invoke_t.hpp>
|
||||
#include <callable_traits/substitution.hpp>
|
||||
#include <callable_traits/arity.hpp>
|
||||
#include <callable_traits/bind_expression.hpp>
|
||||
#include <callable_traits/bind_expression_parser.hpp>
|
||||
#include <callable_traits/is_bind_expression.hpp>
|
||||
#include <callable_traits/shallow_decay.hpp>
|
||||
|
||||
//todo remove?
|
||||
#include <callable_traits/can_invoke_t.hpp>
|
||||
#include <callable_traits/disjunction.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<bool Value, typename T>
|
||||
struct value_type_pair {
|
||||
using type = T;
|
||||
static constexpr const bool value = Value;
|
||||
};
|
||||
}
|
||||
|
||||
namespace no_sfinae {
|
||||
|
||||
template<typename T>
|
||||
using args = typename detail::traits<T>::arg_types;
|
||||
|
||||
template<size_t I, typename T>
|
||||
using arg_at = typename detail::disjunction<
|
||||
detail::value_type_pair<std::tuple_size<args<T>>::value <= I, invalid_type>,
|
||||
detail::value_type_pair<true, typename std::tuple_element<I, no_sfinae::args<T>>::type>
|
||||
>::type;
|
||||
|
||||
template<typename T>
|
||||
using signature = typename detail::traits<T>::function_type;
|
||||
|
||||
|
||||
@@ -39,42 +39,6 @@ namespace callable_traits {
|
||||
using can_dereference = std::integral_constant<bool,
|
||||
can_dereference_t<T>::value
|
||||
>;
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct dereference_if_not_function {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_class_after_dereference
|
||||
{
|
||||
template<typename>
|
||||
struct check {};
|
||||
|
||||
template<typename U, typename K = typename std::enable_if<!std::is_function<typename std::remove_reference<U>::value>::value, U>::type>
|
||||
static typename std::enable_if<
|
||||
std::is_class<
|
||||
typename std::remove_reference<decltype(*std::declval<K>())>::type
|
||||
>::value,
|
||||
std::int8_t
|
||||
>::type test(std::nullptr_t);
|
||||
|
||||
template<typename>
|
||||
static std::int16_t test(...);
|
||||
|
||||
static constexpr const bool value =
|
||||
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using can_dereference_to_class = std::integral_constant<bool,
|
||||
is_class_after_dereference<T>::value
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
using cannot_dereference_to_class = std::integral_constant<bool,
|
||||
!is_class_after_dereference<T>::value
|
||||
>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
/*!
|
||||
@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_CAN_INVOKE_T_HPP
|
||||
#define CALLABLE_TRAITS_CAN_INVOKE_T_HPP
|
||||
|
||||
#include <callable_traits/test_invoke.hpp>
|
||||
#include <callable_traits/substitution.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Dispatch, typename... Args>
|
||||
struct can_invoke_t {
|
||||
|
||||
using callable = typename Dispatch::type;
|
||||
using class_type = typename Dispatch::class_type;
|
||||
using is_member_pointer = typename Dispatch::is_member_pointer;
|
||||
|
||||
using invoker = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
test_invoke<Dispatch, class_type, Args...>,
|
||||
test_invoke<Dispatch, Args...>
|
||||
>::type;
|
||||
|
||||
using test = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<typename Dispatch::invoke_type>(),
|
||||
std::declval<Args>()...
|
||||
)),
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<Args>()...
|
||||
))
|
||||
>::type;
|
||||
|
||||
static constexpr bool value =
|
||||
!std::is_same<substitution_failure, test>{};
|
||||
|
||||
static constexpr int arg_count = invoker::arg_count;
|
||||
};
|
||||
|
||||
template<typename Dispatch>
|
||||
struct can_invoke_t<Dispatch, void> {
|
||||
|
||||
using callable = typename Dispatch::type;
|
||||
using class_type = typename Dispatch::class_type;
|
||||
using is_member_pointer = typename Dispatch::is_member_pointer;
|
||||
|
||||
using invoker = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
test_invoke<Dispatch>,
|
||||
test_invoke<Dispatch, class_type>
|
||||
>::type;
|
||||
|
||||
using invoke_type = typename Dispatch::invoke_type;
|
||||
|
||||
using test = typename std::conditional<
|
||||
is_member_pointer::value,
|
||||
decltype(invoker{}(
|
||||
std::declval<callable>(),
|
||||
std::declval<invoke_type>()
|
||||
)),
|
||||
decltype(invoker{}(std::declval<callable>()))
|
||||
>::type;
|
||||
|
||||
static constexpr bool value =
|
||||
!std::is_same<substitution_failure, test>::value;
|
||||
|
||||
static constexpr int arg_count = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -8,7 +8,7 @@ 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 <callable_traits/ph.hpp>
|
||||
#include <callable_traits/placeholder.hpp>
|
||||
#include <callable_traits/fwd/bind_expression_fwd.hpp>
|
||||
#include <callable_traits/any_arg.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
@@ -26,32 +26,23 @@ namespace callable_traits {
|
||||
using type = typename std::conditional<
|
||||
std::is_placeholder< T >::value == 0,
|
||||
bind_value<T>,
|
||||
ph<std::is_placeholder< T >::value>
|
||||
placeholder<std::is_placeholder< T >::value>
|
||||
>::type;
|
||||
|
||||
using bind_expr = invalid_type;
|
||||
using is_bind_expression = std::false_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct categorize_bind_arg< bind_value<T> > {
|
||||
using type = detail::bind_value<T>;
|
||||
using bind_expr = invalid_type;
|
||||
using is_bind_expression = std::false_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct categorize_bind_arg< std::reference_wrapper<T> > {
|
||||
using type = std::reference_wrapper<T>;
|
||||
using bind_expr = invalid_type;
|
||||
using is_bind_expression = std::false_type;
|
||||
};
|
||||
|
||||
template<int I>
|
||||
struct categorize_bind_arg< ph<I> > {
|
||||
using type = ph<I>;
|
||||
using bind_expr = invalid_type;
|
||||
using is_bind_expression = std::false_type;
|
||||
struct categorize_bind_arg< placeholder<I> > {
|
||||
using type = placeholder<I>;
|
||||
};
|
||||
|
||||
template<typename Callable, typename... Args>
|
||||
@@ -64,9 +55,6 @@ namespace callable_traits {
|
||||
any_arg<>,
|
||||
return_type
|
||||
>::type;
|
||||
|
||||
using bind_expr = bind_expression<Callable, Args...>;
|
||||
using is_bind_expression = std::true_type;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
/*!
|
||||
@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_CONSTRAINTS_HPP
|
||||
#define CALLABLE_TRAITS_CONSTRAINTS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <callable_traits/has_normal_call_operator.hpp>
|
||||
#include <callable_traits/can_dereference.hpp>
|
||||
|
||||
// CALLABLE_TRAITS_REQUIRES_ and CALLABLE_TRAITS_REQUIRES adapted from Range-v3 here:
|
||||
// https://github.com/ericniebler/range-v3/blob/6600e6054513202e61a067de48c4a05ca2b11099/include/range/v3/utility/concepts.hpp#L861
|
||||
// Copyright Eric Niebler 2013-2014
|
||||
|
||||
#define CALLABLE_TRAITS_PP_CAT_(X, Y) X ## Y
|
||||
#define CALLABLE_TRAITS_PP_CAT(X, Y) CALLABLE_TRAITS_PP_CAT_(X, Y)
|
||||
|
||||
#define CALLABLE_TRAITS_REQUIRES_(...) \
|
||||
int CALLABLE_TRAITS_PP_CAT(callable_traits_requires_, __LINE__) = 42, \
|
||||
typename std::enable_if< \
|
||||
(CALLABLE_TRAITS_PP_CAT(callable_traits_requires_, __LINE__) == 43) || (__VA_ARGS__), \
|
||||
bool \
|
||||
>::type constraint_success = true \
|
||||
/**/
|
||||
|
||||
#define CALLABLE_TRAITS_REQUIRES(...) \
|
||||
template< \
|
||||
int CALLABLE_TRAITS_PP_CAT(callable_traits_requires_, __LINE__) = 42, \
|
||||
typename std::enable_if< \
|
||||
(CALLABLE_TRAITS_PP_CAT(callable_traits_requires_, __LINE__) == 43) || (__VA_ARGS__),\
|
||||
bool \
|
||||
>::type constraint_success = true> \
|
||||
/**/
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct callable_dummy {
|
||||
void operator()() {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using default_normal_callable = typename std::conditional<
|
||||
has_normal_call_operator<T>::value,
|
||||
T,
|
||||
callable_dummy
|
||||
>::type;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
/*!
|
||||
@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_DEFAULT_DISPATCH_HPP
|
||||
#define CALLABLE_TRAITS_DEFAULT_DISPATCH_HPP
|
||||
|
||||
template<typename T>
|
||||
struct default_dispatch {
|
||||
static constexpr const bool is_valid = true;
|
||||
static constexpr const bool value = is_valid;
|
||||
using traits = T;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
/*!
|
||||
@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_DEREFERENCEABLE_OBJECT_HPP
|
||||
#define CALLABLE_TRAITS_DEREFERENCEABLE_OBJECT_HPP
|
||||
|
||||
namespace clbl {
|
||||
|
||||
template<typename T>
|
||||
using default_dereferenceable = typename std::conditional<
|
||||
can_dereference<T>::value,
|
||||
T,
|
||||
int*
|
||||
>::type;
|
||||
|
||||
template<
|
||||
typename Ptr,
|
||||
typename std::enable_if<
|
||||
can_dereference<Ptr>::value
|
||||
&& std::is_class<
|
||||
typename std::remove_reference<
|
||||
decltype(*std::declval<default_dereferenceable<Ptr>>())
|
||||
>::type
|
||||
>::value,
|
||||
int*
|
||||
>::type = nullptr
|
||||
>
|
||||
using dereferenceable_object = Ptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
/*!
|
||||
@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_FLAG_MAP_HPP
|
||||
#define CALLABLE_TRAITS_FLAG_MAP_HPP
|
||||
|
||||
#include <callable_traits/flags.hpp>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct flag_map {
|
||||
static_assert(sizeof(T) < 0,
|
||||
"Invalid argument passed to flag_map template.");
|
||||
|
||||
static constexpr flags value = default_;
|
||||
};
|
||||
|
||||
template<> struct flag_map<int> { static constexpr flags value = default_; };
|
||||
template<> struct flag_map<int &> { static constexpr flags value = lref_; };
|
||||
template<> struct flag_map<int &&> { static constexpr flags value = rref_; };
|
||||
template<> struct flag_map<int const> { static constexpr flags value = const_; };
|
||||
template<> struct flag_map<int const &> { static constexpr flags value = const_ | lref_; };
|
||||
template<> struct flag_map<int const &&> { static constexpr flags value = const_ | rref_; };
|
||||
template<> struct flag_map<int volatile> { static constexpr flags value = volatile_; };
|
||||
template<> struct flag_map<int volatile &> { static constexpr flags value = volatile_ | lref_; };
|
||||
template<> struct flag_map<int volatile &&> { static constexpr flags value = volatile_ | rref_; };
|
||||
template<> struct flag_map<int const volatile> { static constexpr flags value = const_ | volatile_; };
|
||||
template<> struct flag_map<int const volatile &> { static constexpr flags value = const_ | volatile_ | lref_; };
|
||||
template<> struct flag_map<int const volatile &&> { static constexpr flags value = const_ | volatile_ | rref_; };
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,164 +0,0 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `flags`
|
||||
|
||||
@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_FLAGS_HPP
|
||||
#define CALLABLE_TRAITS_FLAGS_HPP
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
//! flags are bit flags used to signify cv-qualifiers
|
||||
//! and ref-qualifiers/reference types
|
||||
using flags = std::uint32_t;
|
||||
|
||||
/*
|
||||
This grid is useful for debugging type errors where
|
||||
the error messages often include a `flags` value:
|
||||
|
||||
value | RR LR V C | result
|
||||
--------------------------------------------
|
||||
0 | 0 0 0 0 | default
|
||||
1 | 0 0 0 1 | const
|
||||
2 | 0 0 1 0 | volatile
|
||||
3 | 0 0 1 1 | const volatile
|
||||
--------------------------------------------
|
||||
4 | 0 1 0 0 | lref
|
||||
5 | 0 1 0 1 | const lref
|
||||
6 | 0 1 1 0 | volatile lref
|
||||
7 | 0 1 1 1 | const volatile lref
|
||||
--------------------------------------------
|
||||
8 | 1 0 0 0 | rref
|
||||
9 | 1 0 0 1 | const rref
|
||||
10 | 1 0 1 0 | volatile rref
|
||||
11 | 1 0 1 1 | const volatile rref
|
||||
--------------------------------------------
|
||||
12+ | 1 1 * * | invalid - use `collapse`
|
||||
|
||||
*/
|
||||
|
||||
constexpr flags max_flags_value = 11;
|
||||
|
||||
//! Flag representing the default qualifiers on a type
|
||||
//! or member function overload.
|
||||
constexpr flags default_ = 0;
|
||||
|
||||
//! Flag representing a const qualifier on a type or
|
||||
//! member function overload.
|
||||
constexpr flags const_ = 1;
|
||||
|
||||
//! Flag representing a volatile qualifier on a type
|
||||
//! or member function overload.
|
||||
constexpr flags volatile_ = 2;
|
||||
|
||||
//! Flag representing an lvalue reference type, or
|
||||
//! an lvalue-reference-qualified member function
|
||||
//! overload.
|
||||
constexpr flags lvalue_reference_ = 4;
|
||||
|
||||
//! shorthand for `lvalue_reference_`.
|
||||
constexpr flags lref_ = 4;
|
||||
|
||||
//! shorthand for `const_ | lvalue_reference_`.
|
||||
constexpr flags clref_ = 5;
|
||||
|
||||
//! Flag representing an lvalue reference type, or
|
||||
//! an rvalue-reference-qualified member function
|
||||
//! overload.
|
||||
constexpr flags rvalue_reference_ = 8;
|
||||
|
||||
//! shorthand for `rvalue_reference_`.
|
||||
constexpr flags rref_ = 8;
|
||||
|
||||
constexpr flags cv_ = 3;
|
||||
|
||||
template<flags Flags>
|
||||
using add_const = std::integral_constant<flags, Flags | const_>;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_const = std::integral_constant<flags, Flags & ~const_>;
|
||||
|
||||
template<flags Flags>
|
||||
using is_const = std::integral_constant<bool,
|
||||
(Flags & const_) != 0
|
||||
>;
|
||||
|
||||
template<flags Flags>
|
||||
using add_volatile = std::integral_constant<flags, Flags | volatile_>;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_volatile = std::integral_constant<flags, Flags & ~volatile_>;
|
||||
|
||||
template<flags Flags>
|
||||
using is_volatile = std::integral_constant<bool,
|
||||
(Flags & volatile_) != 0
|
||||
>;
|
||||
|
||||
template<flags Flags>
|
||||
using add_cv = std::integral_constant<flags, Flags | volatile_ | const_>;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_cv = std::integral_constant<flags, Flags & ~volatile_ & ~const_>;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_reference = std::integral_constant<flags, (Flags & ~rref_) & ~lref_>;
|
||||
|
||||
template<flags Flags>
|
||||
using is_lvalue_reference = std::integral_constant<bool, (Flags & lref_) != 0>;
|
||||
|
||||
//is_rvalue_reference uses reference collapsing rules
|
||||
template<flags Flags>
|
||||
using is_rvalue_reference = std::integral_constant<bool, (Flags & (lref_ | rref_)) == rref_>;
|
||||
|
||||
template<flags Flags>
|
||||
using force_lvalue_reference = std::integral_constant<flags, (Flags & ~rref_) | lref_>;
|
||||
|
||||
template<flags Flags>
|
||||
using force_rvalue_reference = std::integral_constant<flags, (Flags & ~lref_) | rref_>;
|
||||
|
||||
template<flags Existing, flags Other>
|
||||
using collapse = std::integral_constant<flags,
|
||||
(Existing & lref_) == 0 ?
|
||||
(Existing | Other)
|
||||
: (Existing | (Other & ~rref_))
|
||||
>;
|
||||
|
||||
template<flags Flags>
|
||||
using add_lvalue_reference = std::integral_constant<flags, lref_ | (Flags & ~rref_)>;
|
||||
|
||||
template<flags Flags>
|
||||
using add_rvalue_reference = collapse<Flags, rref_>;
|
||||
|
||||
template<flags Flags>
|
||||
using guarantee_reference = std::integral_constant<flags,
|
||||
(
|
||||
(Flags & rref_) == 0
|
||||
&& (Flags & lref_) == 0
|
||||
) ?
|
||||
(Flags | lref_) : Flags
|
||||
>;
|
||||
|
||||
template<typename U, typename T = typename std::remove_reference<U>::type>
|
||||
using cv_of = std::integral_constant<flags,
|
||||
(std::is_const<T>::value ? const_ : default_)
|
||||
| (std::is_volatile<T>::value ? volatile_ : default_)
|
||||
>;
|
||||
|
||||
using force_ref = std::true_type;
|
||||
|
||||
template<typename T, typename ForceRef = std::false_type>
|
||||
using ref_of = std::integral_constant<flags,
|
||||
std::is_rvalue_reference<T>::value ? rref_
|
||||
: (std::is_lvalue_reference<T>::value ? lref_
|
||||
: (ForceRef::value ? lref_ : default_))
|
||||
>;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -11,13 +11,11 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#define CALLABLE_TRAITS_FUNCTION_HPP
|
||||
|
||||
#include <callable_traits/set_function_qualifiers.hpp>
|
||||
#include <callable_traits/constraints.hpp>
|
||||
#include <callable_traits/has_normal_call_operator.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
#include <callable_traits/flags.hpp>
|
||||
#include <callable_traits/qualifiers.hpp>
|
||||
#include <callable_traits/member_pointer_utilities.hpp>
|
||||
#include <callable_traits/function_object.hpp>
|
||||
#include <callable_traits/qualifier_traits.hpp>
|
||||
#include <callable_traits/generalized_class.hpp>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
@@ -41,7 +39,6 @@ public:
|
||||
using is_function_general = std::true_type; \
|
||||
\
|
||||
using traits = function; \
|
||||
using callable_traits_tag = function_tag; \
|
||||
using return_type = Return; \
|
||||
using arg_types = std::tuple<Args...>; \
|
||||
using type = Return(Args...) QUAL; \
|
||||
@@ -102,7 +99,6 @@ public:
|
||||
using is_function = std::true_type; \
|
||||
using is_function_general = std::true_type; \
|
||||
using traits = function; \
|
||||
using callable_traits_tag = function_tag; \
|
||||
using return_type = Return; \
|
||||
using arg_types = std::tuple<Args...>; \
|
||||
using type = Return (Args..., ...) QUAL; \
|
||||
@@ -149,7 +145,7 @@ namespace callable_traits {
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct function : function_object<general<unknown>> {
|
||||
struct function : function_object<generalized_class<unknown>> {
|
||||
static constexpr const bool value = false;
|
||||
using traits = function;
|
||||
};
|
||||
@@ -167,11 +163,6 @@ namespace callable_traits {
|
||||
CALLABLE_TRAITS_SPECIALIZE_FUNCTION(volatile &&);
|
||||
CALLABLE_TRAITS_SPECIALIZE_FUNCTION(const volatile &&);
|
||||
|
||||
template<typename T, T Value>
|
||||
struct function<std::integral_constant<T, Value> > {
|
||||
using traits = function<T>;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct function<T*> : function<T> {
|
||||
using traits = function;
|
||||
|
||||
@@ -10,9 +10,8 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef CALLABLE_TRAITS_FUNCTION_OBJECT_HPP
|
||||
#define CALLABLE_TRAITS_FUNCTION_OBJECT_HPP
|
||||
|
||||
#include <callable_traits/general.hpp>
|
||||
#include <callable_traits/generalized_class.hpp>
|
||||
#include <callable_traits/pmf.hpp>
|
||||
#include <callable_traits/has_normal_call_operator.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
|
||||
#include <tuple>
|
||||
@@ -21,6 +20,32 @@ namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct has_normal_call_operator
|
||||
{
|
||||
template<typename N, N Value> struct check { check(std::nullptr_t) {} };
|
||||
|
||||
template<typename U>
|
||||
static std::int8_t test(check<decltype(&U::operator()), &U::operator()>);
|
||||
|
||||
template<typename>
|
||||
static std::int16_t test(...);
|
||||
|
||||
static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
||||
|
||||
};
|
||||
|
||||
struct callable_dummy {
|
||||
void operator()() {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using default_normal_callable = typename std::conditional<
|
||||
has_normal_call_operator<T>::value,
|
||||
T,
|
||||
callable_dummy
|
||||
>::type;
|
||||
|
||||
template<typename General>
|
||||
struct ambiguous_function_object {
|
||||
using arg_types = std::tuple<unknown>;
|
||||
@@ -79,7 +104,7 @@ namespace callable_traits {
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct function_object <general<T U::*> > {
|
||||
struct function_object <generalized_class<T U::*> > {
|
||||
static constexpr const bool value = false;
|
||||
using traits = function_object;
|
||||
};
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*!
|
||||
@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_GENERAL_HPP
|
||||
#define CALLABLE_TRAITS_GENERAL_HPP
|
||||
|
||||
#include <callable_traits/can_dereference.hpp>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct general;
|
||||
|
||||
template<typename T>
|
||||
struct general<T, cannot_dereference_to_class<typename std::remove_reference<T>::type>> {
|
||||
using type = typename std::remove_reference<T>::type;
|
||||
using original_type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct general<T, can_dereference_to_class<typename std::remove_reference<T>::type>> {
|
||||
using type = typename std::remove_reference<decltype(*std::declval<T>())>::type;
|
||||
using original_type = T;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
49
include/callable_traits/generalize.hpp
Normal file
49
include/callable_traits/generalize.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
/*!
|
||||
@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_GENERALIZE_HPP
|
||||
#define CALLABLE_TRAITS_GENERALIZE_HPP
|
||||
|
||||
#include <callable_traits/is_reference_wrapper.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct generalize_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct generalize_t<T, std::integral_constant<bool,
|
||||
can_dereference<T>::value && !is_reference_wrapper<T>::value
|
||||
>>{
|
||||
using type = decltype(*std::declval<T>());
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct generalize_t<T, is_reference_wrapper<T>> {
|
||||
using type = decltype(std::declval<T>().get());
|
||||
};
|
||||
|
||||
// generalize expects a pointer, a reference, or a reference_wrapper.
|
||||
// When T is a pointer, generalize<T> is the resulting type
|
||||
// of the pointer dereferenced. When T is an std::reference_wrapper,
|
||||
// generalize<T> is the underlying reference type. Otherwise, generalize
|
||||
// is T.
|
||||
|
||||
template<typename T>
|
||||
using generalize = typename generalize_t<T>::type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
70
include/callable_traits/generalized_class.hpp
Normal file
70
include/callable_traits/generalized_class.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*!
|
||||
@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_GENERALIZED_CLASS_HPP
|
||||
#define CALLABLE_TRAITS_GENERALIZED_CLASS_HPP
|
||||
|
||||
#include <callable_traits/can_dereference.hpp>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct is_class_after_dereference
|
||||
{
|
||||
template<typename>
|
||||
struct check {};
|
||||
|
||||
template<typename U, typename K = typename std::enable_if<!std::is_function<typename std::remove_reference<U>::value>::value, U>::type>
|
||||
static typename std::enable_if<
|
||||
std::is_class<
|
||||
typename std::remove_reference<decltype(*std::declval<K>())>::type
|
||||
>::value,
|
||||
std::int8_t
|
||||
>::type test(std::nullptr_t);
|
||||
|
||||
template<typename>
|
||||
static std::int16_t test(...);
|
||||
|
||||
static constexpr const bool value =
|
||||
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using can_dereference_to_class = std::integral_constant<bool,
|
||||
is_class_after_dereference<T>::value
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
using cannot_dereference_to_class = std::integral_constant<bool,
|
||||
!is_class_after_dereference<T>::value
|
||||
>;
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct generalized_class;
|
||||
|
||||
template<typename T>
|
||||
struct generalized_class<T, cannot_dereference_to_class<typename std::remove_reference<T>::type>> {
|
||||
using type = typename std::remove_reference<T>::type;
|
||||
using original_type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct generalized_class<T, can_dereference_to_class<typename std::remove_reference<T>::type>> {
|
||||
using type = typename std::remove_reference<decltype(*std::declval<T>())>::type;
|
||||
using original_type = T;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,37 +0,0 @@
|
||||
/*!
|
||||
@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_NORMAL_CALL_OPERATOR_HPP
|
||||
#define CALLABLE_TRAITS_HAS_NORMAL_CALL_OPERATOR_HPP
|
||||
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct has_normal_call_operator
|
||||
{
|
||||
template<typename N, N Value> struct check { check(std::nullptr_t) {} };
|
||||
|
||||
template<typename U>
|
||||
static std::int8_t test(check<decltype(&U::operator()), &U::operator()>);
|
||||
|
||||
template<typename>
|
||||
static std::int16_t test(...);
|
||||
|
||||
static constexpr bool value = sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
/*!
|
||||
@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_IS_BIND_EXPRESSION_HPP
|
||||
#define CALLABLE_TRAITS_IS_BIND_EXPRESSION_HPP
|
||||
|
||||
#include <callable_traits/fwd/bind_expression_fwd.hpp>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct is_bind_expression {
|
||||
static constexpr const bool value = false;
|
||||
};
|
||||
|
||||
template<typename Callable, typename... Args>
|
||||
struct is_bind_expression<bind_expression<Callable, Args...>> {
|
||||
static constexpr const bool value = true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
37
include/callable_traits/is_reference_wrapper.hpp
Normal file
37
include/callable_traits/is_reference_wrapper.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*!
|
||||
@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_IS_REFERENCE_WRAPPER_HPP
|
||||
#define CALLABLE_TRAITS_IS_REFERENCE_WRAPPER_HPP
|
||||
|
||||
#include <callable_traits/can_dereference.hpp>
|
||||
#include <type_traits>
|
||||
#include <memory>
|
||||
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_wrapper_t {
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_wrapper_t<std::reference_wrapper<T>> {
|
||||
using type = std::true_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using is_reference_wrapper = typename is_reference_wrapper_t<shallow_decay<T>>::type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -19,22 +19,19 @@ namespace callable_traits {
|
||||
template<typename T, typename Class>
|
||||
using add_member_pointer = T Class::*;
|
||||
|
||||
namespace mpdetail {
|
||||
template<typename T>
|
||||
struct remove_member_pointer_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_member_pointer_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct remove_member_pointer_t<T U::*>{
|
||||
using type = T;
|
||||
};
|
||||
}
|
||||
template<typename T, typename U>
|
||||
struct remove_member_pointer_t<T U::*>{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using remove_member_pointer =
|
||||
typename mpdetail::remove_member_pointer_t<T>::type;
|
||||
typename remove_member_pointer_t<T>::type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*!
|
||||
@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_NORMALIZE_REFERENCE_HPP
|
||||
#define CALLABLE_TRAITS_NORMALIZE_REFERENCE_HPP
|
||||
|
||||
#include <callable_traits/shallow_decay.hpp>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_wrapper_t {
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct is_reference_wrapper_t<std::reference_wrapper<T>> {
|
||||
using type = std::true_type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using is_reference_wrapper = typename is_reference_wrapper_t<shallow_decay<T>>::type;
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct normalize_reference_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_reference_t<T, std::integral_constant<bool,
|
||||
can_dereference<T>::value && !is_reference_wrapper<T>::value
|
||||
>>{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_reference_t<T, is_reference_wrapper<T>> {
|
||||
using type = decltype(std::declval<T>().get());
|
||||
};
|
||||
|
||||
// normalize_reference expects a pointer, a reference, or a reference_wrapper.
|
||||
// When T is a pointer, normalize_reference<T> is the resulting type
|
||||
// of the pointer dereferenced. When T is an std::reference_wrapper,
|
||||
// normalize_reference<T> is the underlying reference type.
|
||||
|
||||
template<typename T>
|
||||
using normalize_reference = typename normalize_reference_t<T>::type;
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct normalize_ptr_or_reference_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_ptr_or_reference_t<T, std::integral_constant<bool,
|
||||
can_dereference<T>::value && !is_reference_wrapper<T>::value
|
||||
>>{
|
||||
using type = decltype(*std::declval<T>());
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct normalize_ptr_or_reference_t<T, is_reference_wrapper<T>> {
|
||||
using type = decltype(std::declval<T>().get());
|
||||
};
|
||||
|
||||
// normalize_reference expects a pointer, a reference, or a reference_wrapper.
|
||||
// When T is a pointer, normalize_reference<T> is the resulting type
|
||||
// of the pointer dereferenced. When T is an std::reference_wrapper,
|
||||
// normalize_reference<T> is the underlying reference type.
|
||||
|
||||
template<typename T>
|
||||
using normalize_ptr_or_reference = typename normalize_ptr_or_reference_t<T>::type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,41 +0,0 @@
|
||||
/*!
|
||||
Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
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)
|
||||
*/
|
||||
|
||||
#ifndef CALLABLE_TRAITS_PH_HPP
|
||||
#define CALLABLE_TRAITS_PH_HPP
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
template<int I> struct ph;
|
||||
|
||||
}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<int I>
|
||||
struct is_placeholder< callable_traits::ph<I> >
|
||||
{
|
||||
static constexpr const int value = I;
|
||||
};
|
||||
}
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
template<int I>
|
||||
struct ph {
|
||||
|
||||
ph() = default;
|
||||
|
||||
template<typename T>
|
||||
ph(T const &) {
|
||||
static_assert(I == std::is_placeholder<T>::value, "Invalid placeholder");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,18 +1,46 @@
|
||||
/*!
|
||||
@copyright Barrett Adair 2016
|
||||
Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
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)
|
||||
*/
|
||||
|
||||
#ifndef CALLABLE_TRAITS_BIND_PLACEHOLDER_ROUTES_HPP
|
||||
#define CALLABLE_TRAITS_BIND_PLACEHOLDER_ROUTES_HPP
|
||||
#ifndef CALLABLE_TRAITS_PLACEHOLDER_HPP
|
||||
#define CALLABLE_TRAITS_PLACEHOLDER_HPP
|
||||
|
||||
#include <callable_traits/prepend.hpp>
|
||||
#include <callable_traits/tuple_sort.hpp>
|
||||
#include <type_traits>
|
||||
#include <functional>
|
||||
|
||||
namespace callable_traits {
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
namespace detail {
|
||||
|
||||
template<int I>
|
||||
struct placeholder {
|
||||
|
||||
placeholder() = default;
|
||||
|
||||
template<typename T>
|
||||
placeholder(T const &) {
|
||||
static_assert(I == std::is_placeholder<T>::value, "Invalid placeholder");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
namespace std {
|
||||
|
||||
template<int I>
|
||||
struct is_placeholder< callable_traits::detail::placeholder<I> > {
|
||||
static constexpr const int value = I;
|
||||
};
|
||||
}
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Expression, std::size_t OriginalArgIndex, std::size_t PhValue>
|
||||
struct ph_route {
|
||||
@@ -81,10 +109,8 @@ namespace callable_traits {
|
||||
>::type
|
||||
>::type;
|
||||
|
||||
using type = sort_tuple<routed_placeholders, compare_placeholders>;
|
||||
using type = tuple_sort<routed_placeholders, compare_placeholders>;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -12,11 +12,9 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <callable_traits/general.hpp>
|
||||
#include <callable_traits/fwd/function_object_fwd.hpp>
|
||||
#include <callable_traits/function.hpp>
|
||||
#include <callable_traits/traits.hpp>
|
||||
#include <callable_traits/default_dispatch.hpp>
|
||||
#include <callable_traits/member_pointer_utilities.hpp>
|
||||
|
||||
namespace callable_traits {
|
||||
@@ -55,7 +53,6 @@ namespace callable_traits {
|
||||
|
||||
using remove_member_pointer = D;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
using remove_reference = invalid_type;
|
||||
using add_lvalue_reference = invalid_type;
|
||||
using add_rvalue_reference = invalid_type;
|
||||
@@ -68,29 +65,6 @@ namespace callable_traits {
|
||||
|
||||
template<typename>
|
||||
using apply_return = invalid_type;
|
||||
#else
|
||||
using remove_reference = typename base::remove_reference T::*;
|
||||
using add_lvalue_reference = typename base::add_lvalue_reference T::*;
|
||||
using add_rvalue_reference = typename base::add_lvalue_reference T::*;
|
||||
using add_const = typename base::add_const T::*;
|
||||
using add_volatile = typename base::add_volatile T::*;
|
||||
using add_cv = typename base::add_cv T::*;
|
||||
using remove_const = typename base::remove_const T::*;
|
||||
using remove_volatile = typename base::remove_volatile T::*;
|
||||
using remove_cv = typename base::remove_cv T::*;
|
||||
|
||||
template<typename U>
|
||||
using apply_return = detail::add_member_pointer<
|
||||
msvc_workaround::apply_return_helper<base, U>,
|
||||
T
|
||||
>;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
template<typename T, T Value>
|
||||
struct pmd<std::integral_constant<T, Value> > {
|
||||
using traits = pmd<T>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,8 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#define CALLABLE_TRAITS_PMF_HPP
|
||||
|
||||
#include <callable_traits/set_function_qualifiers.hpp>
|
||||
#include <callable_traits/qualifier_traits.hpp>
|
||||
#include <callable_traits/constraints.hpp>
|
||||
#include <callable_traits/has_normal_call_operator.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
#include <callable_traits/flags.hpp>
|
||||
#include <callable_traits/qualifiers.hpp>
|
||||
#include <tuple>
|
||||
|
||||
#define CALLABLE_TRAITS_SPECIALIZE_PMF(QUAL) \
|
||||
@@ -38,7 +35,6 @@ public:
|
||||
using is_function_general = std::false_type; \
|
||||
\
|
||||
using traits = pmf; \
|
||||
using callable_traits_tag = pmf_tag; \
|
||||
using return_type = Return; \
|
||||
using arg_types = std::tuple<Args...>; \
|
||||
using type = Return(T::*)(Args...) QUAL; \
|
||||
@@ -96,7 +92,6 @@ public:
|
||||
using is_function_general = std::false_type; \
|
||||
\
|
||||
using traits = pmf; \
|
||||
using callable_traits_tag = pmf_tag; \
|
||||
using return_type = Return; \
|
||||
using arg_types = std::tuple<Args...>; \
|
||||
using type = Return(CALLABLE_TRAITS_VARARGS_CC T::*)(Args..., ...) QUAL; \
|
||||
@@ -165,11 +160,6 @@ namespace callable_traits {
|
||||
CALLABLE_TRAITS_SPECIALIZE_PMF(const &&);
|
||||
CALLABLE_TRAITS_SPECIALIZE_PMF(volatile &&);
|
||||
CALLABLE_TRAITS_SPECIALIZE_PMF(const volatile &&);
|
||||
|
||||
template<typename T, T Value>
|
||||
struct pmf<std::integral_constant<T, Value> > {
|
||||
using traits = pmf<T>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*!
|
||||
@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_QUALIFIER_TRAITS_HPP
|
||||
#define CALLABLE_TRAITS_QUALIFIER_TRAITS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
class qualifier_traits {
|
||||
|
||||
protected:
|
||||
|
||||
static constexpr flags cv_flags = cv_of<T>::value;
|
||||
static constexpr flags ref_flags = ref_of<T>::value;
|
||||
static constexpr flags q_flags = cv_flags | ref_flags;
|
||||
|
||||
public:
|
||||
|
||||
using is_reference_qualified = std::integral_constant<bool, 0 < ref_flags>;
|
||||
using is_lvalue_reference_qualified = std::integral_constant<bool, ref_flags == lref_>;
|
||||
using is_rvalue_reference_qualified = std::integral_constant<bool, ref_flags == rref_>;
|
||||
using is_const_qualified = std::integral_constant<bool, 0 < (cv_flags & const_)>;
|
||||
using is_volatile_qualified = std::integral_constant<bool, 0 < (cv_flags & volatile_)>;
|
||||
using is_cv_qualified = std::integral_constant<bool, cv_flags == (const_ | volatile_)>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
133
include/callable_traits/qualifiers.hpp
Normal file
133
include/callable_traits/qualifiers.hpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `flags`
|
||||
|
||||
@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_QUALIFIERS_HPP
|
||||
#define CALLABLE_TRAITS_QUALIFIERS_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
//bit flags used to signify cv/ref qualifiers
|
||||
using flags = std::uint32_t;
|
||||
|
||||
/*
|
||||
|
||||
| && & V C |
|
||||
--------------------------------------------
|
||||
0 | 0 0 0 0 | default
|
||||
1 | 0 0 0 1 | const
|
||||
2 | 0 0 1 0 | volatile
|
||||
3 | 0 0 1 1 | const volatile
|
||||
--------------------------------------------
|
||||
4 | 0 1 0 0 | &
|
||||
5 | 0 1 0 1 | const &
|
||||
6 | 0 1 1 0 | volatile &
|
||||
7 | 0 1 1 1 | const volatile &
|
||||
--------------------------------------------
|
||||
8 | 1 0 0 0 | &&
|
||||
9 | 1 0 0 1 | const &&
|
||||
10 | 1 0 1 0 | volatile &&
|
||||
11 | 1 0 1 1 | const volatile &&
|
||||
|
||||
*/
|
||||
|
||||
//! Flag representing the default qualifiers on a type
|
||||
//! or member function overload.
|
||||
constexpr flags default_ = 0;
|
||||
|
||||
//! Flag representing a const qualifier on a type or
|
||||
//! member function overload.
|
||||
constexpr flags const_ = 1;
|
||||
|
||||
//! Flag representing a volatile qualifier on a type
|
||||
//! or member function overload.
|
||||
constexpr flags volatile_ = 2;
|
||||
|
||||
//! Flag representing an lvalue reference type, or
|
||||
//! an lvalue-reference-qualified member function
|
||||
//! overload.
|
||||
constexpr flags lref_ = 4;
|
||||
|
||||
//! Flag representing an lvalue reference type, or
|
||||
//! an rvalue-reference-qualified member function
|
||||
//! overload.
|
||||
constexpr flags rref_ = 8;
|
||||
|
||||
constexpr flags cv_ = 3;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_const = std::integral_constant<flags, Flags & ~const_>;
|
||||
|
||||
template<flags Flags>
|
||||
using is_const = std::integral_constant<bool,
|
||||
(Flags & const_) != 0
|
||||
>;
|
||||
|
||||
template<flags Flags>
|
||||
using remove_volatile = std::integral_constant<flags, Flags & ~volatile_>;
|
||||
|
||||
template<typename U, typename T = typename std::remove_reference<U>::type>
|
||||
using cv_of = std::integral_constant<flags,
|
||||
(std::is_const<T>::value ? const_ : default_)
|
||||
| (std::is_volatile<T>::value ? volatile_ : default_)
|
||||
>;
|
||||
|
||||
template<typename T, typename ForceRef = std::false_type>
|
||||
using ref_of = std::integral_constant<flags,
|
||||
std::is_rvalue_reference<T>::value ? rref_
|
||||
: (std::is_lvalue_reference<T>::value ? lref_
|
||||
: (ForceRef::value ? lref_ : default_))
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
struct flag_map {
|
||||
static_assert(sizeof(T) < 0,
|
||||
"Invalid argument passed to flag_map template.");
|
||||
|
||||
static constexpr flags value = default_;
|
||||
};
|
||||
|
||||
template<> struct flag_map<int> { static constexpr flags value = default_; };
|
||||
template<> struct flag_map<int &> { static constexpr flags value = lref_; };
|
||||
template<> struct flag_map<int &&> { static constexpr flags value = rref_; };
|
||||
template<> struct flag_map<int const> { static constexpr flags value = const_; };
|
||||
template<> struct flag_map<int const &> { static constexpr flags value = const_ | lref_; };
|
||||
template<> struct flag_map<int const &&> { static constexpr flags value = const_ | rref_; };
|
||||
template<> struct flag_map<int volatile> { static constexpr flags value = volatile_; };
|
||||
template<> struct flag_map<int volatile &> { static constexpr flags value = volatile_ | lref_; };
|
||||
template<> struct flag_map<int volatile &&> { static constexpr flags value = volatile_ | rref_; };
|
||||
template<> struct flag_map<int const volatile> { static constexpr flags value = const_ | volatile_; };
|
||||
template<> struct flag_map<int const volatile &> { static constexpr flags value = const_ | volatile_ | lref_; };
|
||||
template<> struct flag_map<int const volatile &&> { static constexpr flags value = const_ | volatile_ | rref_; };
|
||||
|
||||
template<typename T>
|
||||
class qualifier_traits {
|
||||
|
||||
protected:
|
||||
|
||||
static constexpr flags cv_flags = cv_of<T>::value;
|
||||
static constexpr flags ref_flags = ref_of<T>::value;
|
||||
static constexpr flags q_flags = cv_flags | ref_flags;
|
||||
|
||||
public:
|
||||
|
||||
using is_reference_qualified = std::integral_constant<bool, 0 < ref_flags>;
|
||||
using is_lvalue_reference_qualified = std::integral_constant<bool, ref_flags == lref_>;
|
||||
using is_rvalue_reference_qualified = std::integral_constant<bool, ref_flags == rref_>;
|
||||
using is_const_qualified = std::integral_constant<bool, 0 < (cv_flags & const_)>;
|
||||
using is_volatile_qualified = std::integral_constant<bool, 0 < (cv_flags & volatile_)>;
|
||||
using is_cv_qualified = std::integral_constant<bool, cv_flags == (const_ | volatile_)>;
|
||||
};
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -1,53 +0,0 @@
|
||||
/*!
|
||||
@copyright Barrett Adair 2016
|
||||
|
||||
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_DUPLICATE_PLACEHOLDERS_HPP
|
||||
#define CALLABLE_TRAITS_REMOVE_DUPLICATE_PLACEHOLDERS_HPP
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename...>
|
||||
struct remove_duplicate_placeholders {
|
||||
using type = std::tuple<>;
|
||||
};
|
||||
|
||||
template <typename... Args>
|
||||
struct remove_duplicate_placeholders<std::tuple<Args...> > {
|
||||
using type = typename remove_duplicate_placeholders<Args...>::type;
|
||||
};
|
||||
|
||||
//if 1st and 2nd elements use the same placeholder index, remove the second element
|
||||
template<typename PhRoute1, typename PhRoute2, typename... Tail>
|
||||
struct remove_duplicate_placeholders<PhRoute1, PhRoute2, Tail...> {
|
||||
using type = typename std::conditional<
|
||||
PhRoute1::ph_value == PhRoute2::ph_value,
|
||||
typename remove_duplicate_placeholders<PhRoute1, Tail...>::type,
|
||||
typename prepend<PhRoute1, typename remove_duplicate_placeholders<PhRoute2, Tail...>::type>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
//base case
|
||||
template<typename PhRoute1, typename PhRoute2>
|
||||
struct remove_duplicate_placeholders<PhRoute1, PhRoute2> {
|
||||
using type = typename std::conditional<
|
||||
PhRoute1::ph_value == PhRoute2::ph_value,
|
||||
std::tuple<PhRoute1>,
|
||||
std::tuple<PhRoute1, PhRoute2>
|
||||
>::type;
|
||||
};
|
||||
|
||||
//base case
|
||||
template<typename LastPhRoute>
|
||||
struct remove_duplicate_placeholders<LastPhRoute> {
|
||||
using type = std::tuple<LastPhRoute>;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,28 +0,0 @@
|
||||
/*!
|
||||
@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_REMOVE_REFERNCE_IF_PTR_HPP
|
||||
#define CALLABLE_TRAITS_REMOVE_REFERNCE_IF_PTR_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
using remove_reference_if_ptr = typename std::conditional<
|
||||
std::is_pointer<typename std::remove_reference<T>::type>::value,
|
||||
typename std::remove_reference<T>::type,
|
||||
T
|
||||
>::type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -10,8 +10,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef CALLABLE_TRAITS_SET_FUNCTION_QUALIFIERS_HPP
|
||||
#define CALLABLE_TRAITS_SET_FUNCTION_QUALIFIERS_HPP
|
||||
|
||||
#include <callable_traits/flags.hpp>
|
||||
#include <callable_traits/flag_map.hpp>
|
||||
#include <callable_traits/qualifiers.hpp>
|
||||
#include <callable_traits/tags.hpp>
|
||||
|
||||
#define CALLABLE_TRAITS_SET_FUNCTION_QUALIFIERS(QUAL) \
|
||||
|
||||
@@ -22,13 +22,6 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
struct pmf_tag {};
|
||||
struct pmd_tag {};
|
||||
struct function_tag {};
|
||||
struct function_reference_tag : function_tag {};
|
||||
struct function_ptr_tag : function_tag {};
|
||||
struct function_object_tag {};
|
||||
struct ambiguous_function_object_tag : function_object_tag {};
|
||||
struct dummy {};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,8 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#define CALLABLE_TRAITS_DECLVOKE_HPP
|
||||
|
||||
#include <callable_traits/substitution.hpp>
|
||||
#include <callable_traits/normalize_reference.hpp>
|
||||
#include <callable_traits/generalize.hpp>
|
||||
#include <callable_traits/unwrap_reference.hpp>
|
||||
#include <callable_traits/shallow_decay.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
@@ -22,13 +23,13 @@ namespace callable_traits {
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct subst_success {};
|
||||
struct success {};
|
||||
|
||||
template<typename Base, typename T,
|
||||
typename IsBaseOf = std::is_base_of<Base, shallow_decay<T>>,
|
||||
typename IsSame = std::is_same<Base, shallow_decay<T>>>
|
||||
using generalize_if_dissimilar = typename std::conditional<
|
||||
IsBaseOf::value || IsSame::value, T, normalize_ptr_or_reference<T>
|
||||
IsBaseOf::value || IsSame::value, T, generalize<T>
|
||||
>::type;
|
||||
|
||||
template<typename...>
|
||||
@@ -42,7 +43,7 @@ namespace callable_traits {
|
||||
template<typename P, typename U, typename... Rgs,
|
||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
||||
auto operator()(P&& p, U&& u, Rgs&&... rgs) const ->
|
||||
subst_success<decltype((std::declval<Obj>().*p)(std::forward<Rgs>(rgs)...))>;
|
||||
success<decltype((std::declval<Obj>().*p)(std::forward<Rgs>(rgs)...))>;
|
||||
|
||||
auto operator()(...) const -> substitution_failure;
|
||||
|
||||
@@ -57,7 +58,7 @@ namespace callable_traits {
|
||||
template<typename P, typename U,
|
||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
||||
auto operator()(P&& p, U&& u) const ->
|
||||
subst_success<decltype((std::declval<Obj>().*p))>;
|
||||
success<decltype((std::declval<Obj>().*p))>;
|
||||
|
||||
auto operator()(...) const -> substitution_failure;
|
||||
|
||||
@@ -68,9 +69,9 @@ namespace callable_traits {
|
||||
struct test_invoke<F, Args...> {
|
||||
|
||||
template<typename T, typename... Rgs,
|
||||
typename U = normalize_reference<T&&>>
|
||||
typename U = unwrap_reference<T&&>>
|
||||
auto operator()(T&& t, Rgs&&... rgs) const ->
|
||||
subst_success<decltype(std::declval<U>()(std::forward<Rgs>(rgs)...))>;
|
||||
success<decltype(std::declval<U>()(std::forward<Rgs>(rgs)...))>;
|
||||
|
||||
auto operator()(...) const -> substitution_failure;
|
||||
|
||||
|
||||
@@ -11,15 +11,12 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#define CALLABLE_TRAITS_TRAITS_HPP
|
||||
|
||||
|
||||
#include <callable_traits/general.hpp>
|
||||
#include <callable_traits/generalized_class.hpp>
|
||||
#include <callable_traits/disjunction.hpp>
|
||||
#include <callable_traits/remove_reference_if_ptr.hpp>
|
||||
#include <callable_traits/default_dispatch.hpp>
|
||||
#include <callable_traits/fwd/pmd_fwd.hpp>
|
||||
#include <callable_traits/fwd/pmf_fwd.hpp>
|
||||
#include <callable_traits/fwd/function_fwd.hpp>
|
||||
#include <callable_traits/fwd/function_object_fwd.hpp>
|
||||
#include <callable_traits/is_bind_expression.hpp>
|
||||
#include <callable_traits/bind_expression_traits.hpp>
|
||||
#include <callable_traits/shallow_decay.hpp>
|
||||
|
||||
@@ -29,14 +26,21 @@ namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
using remove_reference_if_ptr = typename std::conditional<
|
||||
std::is_pointer<typename std::remove_reference<T>::type>::value,
|
||||
typename std::remove_reference<T>::type,
|
||||
T
|
||||
>::type;
|
||||
|
||||
template<typename T>
|
||||
using traits = typename disjunction<
|
||||
bind_expression_traits<shallow_decay<T>>,
|
||||
function_object<general<T>>,
|
||||
function_object<generalized_class<T>>,
|
||||
function<remove_reference_if_ptr<T>>,
|
||||
pmf<shallow_decay<T>>,
|
||||
pmd<shallow_decay<T>>,
|
||||
function_object<general<T>>
|
||||
function_object<generalized_class<T>>
|
||||
>::traits;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
#ifndef CALLABLE_TRAITS_TUPLE_GROUP_BY_HPP
|
||||
#define CALLABLE_TRAITS_TUPLE_GROUP_BY_HPP
|
||||
|
||||
#include <callable_traits/sort_tuple.hpp>
|
||||
#include <callable_traits/tuple_sort.hpp>
|
||||
#include <callable_traits/prepend.hpp>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
@@ -108,7 +108,7 @@ namespace callable_traits {
|
||||
using group_by_values = typename distinct_group_by_values<Tup, Pred>::type;
|
||||
|
||||
using type = typename group_by_impl<
|
||||
sort_tuple<Tup, sort_predicate>,
|
||||
tuple_sort<Tup, sort_predicate>,
|
||||
group_by_values,
|
||||
Pred,
|
||||
std::make_index_sequence<std::tuple_size<group_by_values>::value>
|
||||
|
||||
@@ -107,7 +107,7 @@ namespace callable_traits {
|
||||
};
|
||||
|
||||
template<typename Tup, template<class, class> class Pred>
|
||||
using sort_tuple = typename sort_impl<Tup, predicate<Tup, Pred>>::type;
|
||||
using tuple_sort = typename sort_impl<Tup, predicate<Tup, Pred>>::type;
|
||||
}
|
||||
}
|
||||
|
||||
35
include/callable_traits/unwrap_reference.hpp
Normal file
35
include/callable_traits/unwrap_reference.hpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/*!
|
||||
@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_UNWRAP_REFERENCE_HPP
|
||||
#define CALLABLE_TRAITS_UNWRAP_REFERENCE_HPP
|
||||
|
||||
#include <callable_traits/is_reference_wrapper.hpp>
|
||||
#include <type_traits>
|
||||
|
||||
namespace callable_traits {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T, typename = std::true_type>
|
||||
struct unwrap_reference_t {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct unwrap_reference_t<T, is_reference_wrapper<T>> {
|
||||
using type = decltype(std::declval<T>().get());
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using unwrap_reference = typename unwrap_reference_t<T>::type;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user