Skip to content
Snippets Groups Projects

Add implementation of std::is_callable

Merged Carsten Gräser requested to merge feature/is_callable into master
3 files
+ 158
0
Compare changes
  • Side-by-side
  • Inline
Files
3
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
#ifndef DUNE_COMMON_STD_TYPE_TRAITS_HH
#define DUNE_COMMON_STD_TYPE_TRAITS_HH
#include <type_traits>
#include <dune/common/typetraits.hh>
#include <dune/common/typeutilities.hh>
namespace Dune
{
@@ -95,6 +99,82 @@ namespace Std
#endif
namespace Imp {
// If R is void we only need to check if F can be called
// with given Args... list. If this is not possible
// result_of_t is not defined and this overload is disabled.
template<class R, class F, class... Args,
std::enable_if_t<
std::is_same<void_t<std::result_of_t<F(Args...)>>, R>::value
, int> = 0>
std::true_type is_callable_helper(PriorityTag<2>)
{ return {}; }
// Check if result of F(Args...) can be converted to R.
// If F cannot even be called with given Args... then
// result_of_t is not defined and this overload is disabled.
template<class R, class F, class... Args,
std::enable_if_t<
std::is_convertible<std::result_of_t<F(Args...)>, R>::value
, int> = 0>
std::true_type is_callable_helper(PriorityTag<1>)
{ return {}; }
// If none of the above matches, F can either not be called
// with given Args..., or the result cannot be converted to
// void, or R is not void.
template<class R, class F, class... Args>
std::false_type is_callable_helper(PriorityTag<0>)
{ return {}; }
}
/**
* \brief Traits class to check if function is callable
*
* \tparam D Function descriptor
* \tparam R Return value
*
* If D = F(Args...) this checks if F can be called with an
* argument list of type Args..., and if the return value can
* be converted to R. If R is void, any return type is accepted.
* The result is encoded by deriving from std::integral_constant<bool, result>.
*
* If D is not of the form D = F(Args...) this class is not defined.
*
* This implements std::is_callable as proposed in N4446 for C++17.
*/
template <class D, class R= void>
struct is_callable;
/**
* \brief Traits class to check if function is callable
*
* \tparam D Function descriptor
* \tparam R Return value
*
* If D = F(Args...) this checks if F can be called with an
* argument list of type Args..., and if the return value can
* be converted to R. If R is void, any return type is accepted.
* The result is encoded by deriving from std::integral_constant<bool, result>.
*
* If D is not of the form D = F(Args...) this class is not defined.
*
* This implements std::is_callable as proposed in N4446 for C++17.
*/
template <class F, class... Args, class R>
struct is_callable< F(Args...), R> :
decltype(Imp::is_callable_helper<R, F, Args...>(PriorityTag<42>()))
{};
} // namespace Std
} // namespace Dune
Loading