code cleanup minutia

This commit is contained in:
badair
2016-03-28 04:00:04 -05:00
parent ebe63eac82
commit 3912f37612
39 changed files with 515 additions and 981 deletions

View File

@@ -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)
};
}
}

View File

@@ -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;

View File

@@ -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
>;

View File

@@ -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;
};

View File

@@ -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
>;

View File

@@ -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;

View File

@@ -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
>;
}
}

View File

@@ -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

View File

@@ -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;
};
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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

View 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

View 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

View File

@@ -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

View File

@@ -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

View 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

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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>;
};
}
}

View File

@@ -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>;
};
}
}

View File

@@ -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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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) \

View File

@@ -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 {};
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View 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