add boost on mac
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
/*!
|
||||
@file
|
||||
|
||||
@Copyright Barrett Adair 2015-2017
|
||||
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 BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
||||
#define BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
||||
|
||||
#include <boost/callable_traits/detail/config.hpp>
|
||||
#include <boost/callable_traits/detail/forward_declarations.hpp>
|
||||
#include <boost/callable_traits/detail/utility.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost { namespace callable_traits { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct can_dereference_t
|
||||
{
|
||||
template<typename>
|
||||
struct check {};
|
||||
|
||||
template<typename U>
|
||||
static std::int8_t test(
|
||||
check<typename std::remove_reference<decltype(*std::declval<U>())>::type>*
|
||||
);
|
||||
|
||||
template<typename>
|
||||
static std::int16_t test(...);
|
||||
|
||||
static constexpr const bool value =
|
||||
sizeof(test<T>(nullptr)) == sizeof(std::int8_t);
|
||||
};
|
||||
|
||||
//returns std::true_type for pointers and smart pointers
|
||||
template<typename T>
|
||||
using can_dereference = std::integral_constant<bool,
|
||||
can_dereference_t<T>::value>;
|
||||
|
||||
|
||||
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());
|
||||
};
|
||||
|
||||
// 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<T> is T.
|
||||
template<typename T>
|
||||
using generalize = typename generalize_t<T>::type;
|
||||
|
||||
// handles the member pointer rules of INVOKE
|
||||
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, generalize<T>>::type;
|
||||
|
||||
template<typename Traits, bool = Traits::is_const_member::value
|
||||
|| Traits::is_volatile_member::value
|
||||
|| Traits::is_lvalue_reference_member::value
|
||||
|| Traits::is_rvalue_reference_member::value>
|
||||
struct test_invoke {
|
||||
|
||||
template<typename... Rgs,
|
||||
typename U = typename Traits::type>
|
||||
auto operator()(int, Rgs&&... rgs) const ->
|
||||
success<decltype(std::declval<U>()(static_cast<Rgs&&>(rgs)...))>;
|
||||
|
||||
auto operator()(long, ...) const -> substitution_failure;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct test_invoke<function<F>, true /*abominable*/> {
|
||||
auto operator()(...) const -> substitution_failure;
|
||||
};
|
||||
|
||||
template<typename Pmf, bool Ignored>
|
||||
struct test_invoke<pmf<Pmf>, Ignored> {
|
||||
|
||||
using class_t = typename pmf<Pmf>::class_type;
|
||||
|
||||
template<typename U, typename... Rgs,
|
||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
||||
auto operator()(int, U&& u, Rgs&&... rgs) const ->
|
||||
success<decltype((std::declval<Obj>().*std::declval<Pmf>())(static_cast<Rgs&&>(rgs)...))>;
|
||||
|
||||
auto operator()(long, ...) const -> substitution_failure;
|
||||
};
|
||||
|
||||
template<typename Pmd, bool Ignored>
|
||||
struct test_invoke<pmd<Pmd>, Ignored> {
|
||||
|
||||
using class_t = typename pmd<Pmd>::class_type;
|
||||
|
||||
template<typename U,
|
||||
typename Obj = generalize_if_dissimilar<class_t, U&&>>
|
||||
auto operator()(int, U&& u) const ->
|
||||
success<decltype(std::declval<Obj>().*std::declval<Pmd>())>;
|
||||
|
||||
auto operator()(long, ...) const -> substitution_failure;
|
||||
};
|
||||
|
||||
template<typename T, typename... Args>
|
||||
struct is_invocable_impl {
|
||||
using traits = detail::traits<T>;
|
||||
using test = detail::test_invoke<traits>;
|
||||
using result = decltype(test{}(0, ::std::declval<Args>()...));
|
||||
using type = std::integral_constant<bool, result::value>;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
struct is_invocable_impl<void, Args...> {
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
template<typename IsInvocable, typename Ret, typename T, typename... Args>
|
||||
struct is_invocable_r_impl {
|
||||
using traits = detail::traits<T>;
|
||||
using test = detail::test_invoke<traits>;
|
||||
using result = decltype(test{}(0, ::std::declval<Args>()...));
|
||||
using type = std::integral_constant<bool,
|
||||
std::is_convertible<typename result::_::type, Ret>::value
|
||||
|| std::is_same<Ret, void>::value>;
|
||||
};
|
||||
|
||||
template<typename Ret, typename T, typename... Args>
|
||||
struct is_invocable_r_impl<std::false_type, Ret, T, Args...> {
|
||||
using type = std::false_type;
|
||||
};
|
||||
|
||||
}}} // namespace boost::callable_traits::detail
|
||||
|
||||
#endif // #ifndef BOOST_CLBL_TRTS_IS_INVOCABLE_IMPL_HPP
|
||||
Reference in New Issue
Block a user