Fix helper header when using c++17 (#1666)
This will fix issue #1621. It also adds tests for is_callable with c++11, c++14, and c++17.
The fallback implementation was completely broken so I rewrote it so it pass the tests as well. This should be used instead of PR #1631.
[ROCm/clr commit: 57b1b03261]
Esse commit está contido em:
@@ -27,6 +27,26 @@ THE SOFTWARE.
|
||||
// std::false_type, std result_of and std::true_type.
|
||||
#include <utility> // For std::declval.
|
||||
|
||||
#ifdef __has_include // Check if __has_include is present
|
||||
# if __has_include(<version>) // Check for version header
|
||||
# include <version>
|
||||
# if defined(__cpp_lib_is_invocable) && !defined(HIP_HAS_INVOCABLE)
|
||||
# define HIP_HAS_INVOCABLE __cpp_lib_is_invocable
|
||||
# endif
|
||||
# if defined(__cpp_lib_result_of_sfinae) && !defined(HIP_HAS_RESULT_OF_SFINAE)
|
||||
# define HIP_HAS_RESULT_OF_SFINAE __cpp_lib_result_of_sfinae
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef HIP_HAS_INVOCABLE
|
||||
#define HIP_HAS_INVOCABLE 0
|
||||
#endif
|
||||
|
||||
#ifndef HIP_HAS_RESULT_OF_SFINAE
|
||||
#define HIP_HAS_RESULT_OF_SFINAE 0
|
||||
#endif
|
||||
|
||||
namespace std { // TODO: these should be removed as soon as possible.
|
||||
#if (__cplusplus < 201406L)
|
||||
#if (__cplusplus < 201402L)
|
||||
@@ -48,58 +68,56 @@ namespace hip_impl {
|
||||
template <typename...>
|
||||
using void_t_ = void;
|
||||
|
||||
#if (__cplusplus < 201402L)
|
||||
template <FunctionalProcedure F, unsigned int n = 0u, typename = void>
|
||||
struct is_callable_impl : is_callable_impl<F, n + 1u> {};
|
||||
#if HIP_HAS_INVOCABLE
|
||||
template <typename, typename = void>
|
||||
struct is_callable_impl;
|
||||
|
||||
// Pointer to member function, call through non-pointer.
|
||||
template <FunctionalProcedure F, typename C, typename... Ts>
|
||||
struct is_callable_impl<
|
||||
F(C, Ts...), 0u,
|
||||
void_t_<decltype((std::declval<C>().*std::declval<F>())(std::declval<Ts>()...))> >
|
||||
: std::true_type {};
|
||||
|
||||
// Pointer to member function, call through pointer.
|
||||
template <FunctionalProcedure F, typename C, typename... Ts>
|
||||
struct is_callable_impl<
|
||||
F(C, Ts...), 1u,
|
||||
void_t_<decltype(((*std::declval<C>()).*std::declval<F>())(std::declval<Ts>()...))> >
|
||||
: std::true_type {};
|
||||
|
||||
// Pointer to member data, call through non-pointer, no args.
|
||||
template <FunctionalProcedure F, typename C>
|
||||
struct is_callable_impl<F(C), 2u, void_t_<decltype(std::declval<C>().*std::declval<F>())> >
|
||||
: std::true_type {};
|
||||
|
||||
// Pointer to member data, call through pointer, no args.
|
||||
template <FunctionalProcedure F, typename C>
|
||||
struct is_callable_impl<F(C), 3u, void_t_<decltype(*std::declval<C>().*std::declval<F>())> >
|
||||
: std::true_type {};
|
||||
|
||||
// General call, n args.
|
||||
template <FunctionalProcedure F, typename... Ts>
|
||||
struct is_callable_impl<F(Ts...), 4u, void_t_<decltype(std::declval<F>()(std::declval<Ts>()...))> >
|
||||
: std::true_type {};
|
||||
|
||||
// Not callable.
|
||||
template <FunctionalProcedure F>
|
||||
struct is_callable_impl<F, 5u> : std::false_type {};
|
||||
#elif (__cplusplus < 201703L)
|
||||
struct is_callable_impl<F(Ts...)> : std::is_invocable<F, Ts...> {};
|
||||
#elif HIP_HAS_RESULT_OF_SFINAE
|
||||
template <typename, typename = void>
|
||||
struct is_callable_impl : std::false_type {};
|
||||
|
||||
template <FunctionalProcedure F, typename... Ts>
|
||||
struct is_callable_impl<F(Ts...), void_t_<typename std::result_of<F(Ts...)>::type > > : std::true_type {};
|
||||
#else
|
||||
template <class Base, class T, class Derived>
|
||||
auto simple_invoke(T Base::*pmd, Derived&& ref)
|
||||
-> decltype(static_cast<Derived&&>(ref).*pmd);
|
||||
|
||||
template <class PMD, class Pointer>
|
||||
auto simple_invoke(PMD&& pmd, Pointer&& ptr)
|
||||
-> decltype((*static_cast<Pointer&&>(ptr)).*static_cast<PMD&&>(pmd));
|
||||
|
||||
// C++17
|
||||
template <class Base, class T, class Derived>
|
||||
auto simple_invoke(T Base::*pmd, const std::reference_wrapper<Derived>& ref)
|
||||
-> decltype(ref.get().*pmd);
|
||||
|
||||
template <class Base, class T, class Derived, class... Args>
|
||||
auto simple_invoke(T Base::*pmf, Derived&& ref, Args&&... args)
|
||||
-> decltype((static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...));
|
||||
|
||||
template <class PMF, class Pointer, class... Args>
|
||||
auto simple_invoke(PMF&& pmf, Pointer&& ptr, Args&&... args)
|
||||
-> decltype(((*static_cast<Pointer&&>(ptr)).*static_cast<PMF&&>(pmf))(static_cast<Args&&>(args)...));
|
||||
|
||||
template <class Base, class T, class Derived, class... Args>
|
||||
auto simple_invoke(T Base::*pmf, const std::reference_wrapper<Derived>& ref, Args&&... args)
|
||||
-> decltype((ref.get().*pmf)(static_cast<Args&&>(args)...));
|
||||
|
||||
template<class F, class... Ts>
|
||||
auto simple_invoke(F&& f, Ts&&... xs)
|
||||
-> decltype(f(static_cast<Ts&&>(xs)...));
|
||||
|
||||
template <typename, typename = void>
|
||||
struct is_callable_impl : std::false_type {};
|
||||
|
||||
template <FunctionalProcedure F, typename... Ts>
|
||||
struct is_callable_impl<F(Ts...), void_t_<std::invoke_result<F(Ts...)> > > : std::true_type {};
|
||||
struct is_callable_impl<F(Ts...), void_t_<decltype(simple_invoke(std::declval<F>(), std::declval<Ts>()...))> >
|
||||
: std::true_type {};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename Call>
|
||||
struct is_callable : is_callable_impl<Call> {};
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../test_common.cpp HIPCC_OPTIONS -std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include "is_callable_test.hpp"
|
||||
#include <test_common.h>
|
||||
|
||||
int main() { passed(); }
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../test_common.cpp HIPCC_OPTIONS -std=c++11 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
// Ensure fallback path is chosen
|
||||
#define HIP_HAS_RESULT_OF_SFINAE 0
|
||||
#define HIP_HAS_INVOCABLE 0
|
||||
#include "is_callable_test.hpp"
|
||||
#include <test_common.h>
|
||||
|
||||
int main() { passed(); }
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../test_common.cpp HIPCC_OPTIONS -std=c++14 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include "is_callable_test.hpp"
|
||||
#include <test_common.h>
|
||||
|
||||
int main() { passed(); }
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright (c) 2019 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
/* HIT_START
|
||||
* BUILD: %t %s ../test_common.cpp HIPCC_OPTIONS -std=c++17 EXCLUDE_HIP_PLATFORM nvcc
|
||||
* TEST: %t
|
||||
* HIT_END
|
||||
*/
|
||||
|
||||
#include "is_callable_test.hpp"
|
||||
#include <test_common.h>
|
||||
|
||||
int main() { passed(); }
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
Copyright (c) 2017 - present Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <hip/hcc_detail/helpers.hpp>
|
||||
#include <memory>
|
||||
|
||||
using hip_impl::is_callable;
|
||||
|
||||
template<int N>
|
||||
struct callable_rank : callable_rank<N-1>
|
||||
{};
|
||||
|
||||
template<>
|
||||
struct callable_rank<0>
|
||||
{};
|
||||
|
||||
struct test1
|
||||
{
|
||||
struct is_callable_class
|
||||
{
|
||||
void operator()(int) const
|
||||
{
|
||||
}
|
||||
};
|
||||
struct callable_test_param {};
|
||||
|
||||
void is_callable_function(int)
|
||||
{
|
||||
}
|
||||
|
||||
struct is_callable_rank_class
|
||||
{
|
||||
void operator()(int, callable_rank<3>) const
|
||||
{
|
||||
}
|
||||
|
||||
void operator()(int, callable_rank<4>) const
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(is_callable<is_callable_class(int)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_class(long)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_class(double)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_class(const int&)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_class(const long&)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_class(const double&)>::value, "Not callable");
|
||||
static_assert(not is_callable<is_callable_class(callable_test_param)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_class()>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_class(int, int)>::value, "callable failed");
|
||||
|
||||
typedef void (*is_callable_function_pointer)(int);
|
||||
static_assert(is_callable<is_callable_function_pointer(int)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_function_pointer(long)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_function_pointer(double)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_function_pointer(const int&)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_function_pointer(const long&)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_function_pointer(const double&)>::value, "Not callable");
|
||||
static_assert(not is_callable<is_callable_function_pointer(callable_test_param)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_function_pointer()>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_function_pointer(int, int)>::value, "callable failed");
|
||||
|
||||
static_assert(is_callable<is_callable_rank_class(int, callable_rank<3>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(long, callable_rank<3>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(double, callable_rank<3>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const int&, callable_rank<3>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const long&, callable_rank<3>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const double&, callable_rank<3>)>::value, "Not callable");
|
||||
|
||||
static_assert(is_callable<is_callable_rank_class(int, callable_rank<4>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(long, callable_rank<4>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(double, callable_rank<4>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const int&, callable_rank<4>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const long&, callable_rank<4>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const double&, callable_rank<4>)>::value, "Not callable");
|
||||
|
||||
static_assert(is_callable<is_callable_rank_class(int, callable_rank<5>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(long, callable_rank<5>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(double, callable_rank<5>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const int&, callable_rank<5>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const long&, callable_rank<5>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const double&, callable_rank<5>)>::value, "Not callable");
|
||||
|
||||
static_assert(is_callable<is_callable_rank_class(int, callable_rank<6>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(long, callable_rank<6>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(double, callable_rank<6>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const int&, callable_rank<6>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const long&, callable_rank<6>)>::value, "Not callable");
|
||||
static_assert(is_callable<is_callable_rank_class(const double&, callable_rank<6>)>::value, "Not callable");
|
||||
|
||||
static_assert(not is_callable<is_callable_rank_class(int, callable_rank<1>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(long, callable_rank<1>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(double, callable_rank<1>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(const int&, callable_rank<1>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(const long&, callable_rank<1>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(const double&, callable_rank<1>)>::value, "callable failed");
|
||||
|
||||
static_assert(not is_callable<is_callable_rank_class(callable_test_param, callable_test_param)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(callable_rank<3>, callable_test_param)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(callable_rank<4>, callable_test_param)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(callable_test_param, callable_rank<3>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(callable_test_param, callable_rank<4>)>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class()>::value, "callable failed");
|
||||
static_assert(not is_callable<is_callable_rank_class(int, int)>::value, "callable failed");
|
||||
};
|
||||
|
||||
struct test2
|
||||
{
|
||||
typedef int(callable_rank<0>::*fn)(int);
|
||||
|
||||
static_assert(is_callable<fn(callable_rank<0>&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fn(callable_rank<1>&, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fn(callable_rank<0>&)>::value, "Failed");
|
||||
static_assert(not is_callable<fn(callable_rank<0> const&, int)>::value, "Failed");
|
||||
};
|
||||
|
||||
struct test3
|
||||
{
|
||||
typedef int(callable_rank<0>::*fn)(int);
|
||||
|
||||
typedef callable_rank<0>* T;
|
||||
typedef callable_rank<1>* DT;
|
||||
typedef const callable_rank<0>* CT;
|
||||
typedef std::unique_ptr<callable_rank<0>> ST;
|
||||
|
||||
static_assert(is_callable<fn(T&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fn(DT&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fn(const T&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fn(T&&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fn(ST, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fn(CT&, int)>::value, "Failed");
|
||||
|
||||
};
|
||||
|
||||
struct test4
|
||||
{
|
||||
typedef int(callable_rank<0>::*fn);
|
||||
|
||||
static_assert(not is_callable<fn()>::value, "Failed");
|
||||
};
|
||||
|
||||
struct test5
|
||||
{
|
||||
typedef int(callable_rank<0>::*fn);
|
||||
|
||||
static_assert(is_callable<fn(callable_rank<0>&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(callable_rank<0>&&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(const callable_rank<0>&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(callable_rank<1>&)>::value, "Failed");
|
||||
};
|
||||
|
||||
struct test6
|
||||
{
|
||||
typedef int(callable_rank<0>::*fn);
|
||||
|
||||
typedef callable_rank<0>* T;
|
||||
typedef callable_rank<1>* DT;
|
||||
typedef const callable_rank<0>* CT;
|
||||
typedef std::unique_ptr<callable_rank<0>> ST;
|
||||
|
||||
static_assert(is_callable<fn(T&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(DT&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(const T&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(T&&)>::value, "Failed");
|
||||
static_assert(is_callable<fn(ST)>::value, "Failed");
|
||||
static_assert(is_callable<fn(CT&)>::value, "Failed");
|
||||
|
||||
};
|
||||
|
||||
struct test7
|
||||
{
|
||||
typedef void(*fp)(callable_rank<0>&, int);
|
||||
|
||||
static_assert(is_callable<fp(callable_rank<0>&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fp(callable_rank<1>&, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fp(const callable_rank<0>&, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fp()>::value, "Failed");
|
||||
static_assert(not is_callable<fp(callable_rank<0>&)>::value, "Failed");
|
||||
};
|
||||
|
||||
struct test8
|
||||
{
|
||||
typedef void(&fp)(callable_rank<0>&, int);
|
||||
|
||||
static_assert(is_callable<fp(callable_rank<0>&, int)>::value, "Failed");
|
||||
static_assert(is_callable<fp(callable_rank<1>&, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fp(const callable_rank<0>&, int)>::value, "Failed");
|
||||
static_assert(not is_callable<fp()>::value, "Failed");
|
||||
static_assert(not is_callable<fp(callable_rank<0>&)>::value, "Failed");
|
||||
};
|
||||
Referência em uma Nova Issue
Bloquear um usuário