Added tests for rclcpp::function_traits and work around expression SFINAE
This commit is contained in:
parent
5795861009
commit
9f65b9dd59
5 changed files with 390 additions and 59 deletions
|
@ -22,6 +22,7 @@ if(AMENT_ENABLE_TESTING)
|
||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
|
ament_add_gtest(test_function_traits test/test_function_traits.cpp)
|
||||||
ament_add_gtest(test_mapped_ring_buffer test/test_mapped_ring_buffer.cpp)
|
ament_add_gtest(test_mapped_ring_buffer test/test_mapped_ring_buffer.cpp)
|
||||||
ament_add_gtest(test_intra_process_manager test/test_intra_process_manager.cpp)
|
ament_add_gtest(test_intra_process_manager test/test_intra_process_manager.cpp)
|
||||||
if(TARGET test_intra_process_manager)
|
if(TARGET test_intra_process_manager)
|
||||||
|
|
|
@ -57,34 +57,42 @@ struct AnySubscriptionCallback
|
||||||
|
|
||||||
AnySubscriptionCallback(const AnySubscriptionCallback &) = default;
|
AnySubscriptionCallback(const AnySubscriptionCallback &) = default;
|
||||||
|
|
||||||
template<typename CallbackT,
|
template<
|
||||||
typename std::enable_if<
|
typename CallbackT,
|
||||||
function_traits<CallbackT>::arity == 1
|
std::size_t Arity = 1
|
||||||
>::type * = nullptr,
|
|
||||||
typename std::enable_if<
|
|
||||||
std::is_same<
|
|
||||||
typename function_traits<CallbackT>::template argument_type<0>,
|
|
||||||
typename std::shared_ptr<MessageT>
|
|
||||||
>::value
|
|
||||||
>::type * = nullptr
|
|
||||||
>
|
>
|
||||||
void set(CallbackT callback)
|
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
|
||||||
|
set(
|
||||||
|
CallbackT callback,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
typename function_traits<CallbackT>::template argument_type<0>,
|
||||||
|
typename std::shared_ptr<MessageT>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr)
|
||||||
{
|
{
|
||||||
shared_ptr_callback = callback;
|
shared_ptr_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename CallbackT,
|
template<
|
||||||
typename std::enable_if<
|
typename CallbackT,
|
||||||
function_traits<CallbackT>::arity == 2
|
std::size_t Arity = 2
|
||||||
>::type * = nullptr,
|
|
||||||
typename std::enable_if<
|
|
||||||
std::is_same<
|
|
||||||
typename function_traits<CallbackT>::template argument_type<0>,
|
|
||||||
typename std::shared_ptr<MessageT>
|
|
||||||
>::value
|
|
||||||
>::type * = nullptr
|
|
||||||
>
|
>
|
||||||
void set(CallbackT callback)
|
typename std::enable_if<rclcpp::arity_comparator<Arity, CallbackT>::value, void>::type
|
||||||
|
set(
|
||||||
|
CallbackT callback,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
typename function_traits<CallbackT>::template argument_type<0>,
|
||||||
|
typename std::shared_ptr<MessageT>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
typename function_traits<CallbackT>::template argument_type<1>,
|
||||||
|
rmw_message_info_t
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<
|
static_assert(std::is_same<
|
||||||
typename function_traits<CallbackT>::template argument_type<1>,
|
typename function_traits<CallbackT>::template argument_type<1>,
|
||||||
|
|
|
@ -58,6 +58,12 @@ struct function_traits<ReturnTypeT (ClassT::*)(Args ...) const>
|
||||||
: public function_traits<ReturnTypeT(ClassT &, Args ...)>
|
: public function_traits<ReturnTypeT(ClassT &, Args ...)>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
template<std::size_t Arity, typename FunctorT>
|
||||||
|
struct arity_comparator
|
||||||
|
{
|
||||||
|
static constexpr bool value = (Arity == function_traits<FunctorT>::arity);
|
||||||
|
};
|
||||||
|
|
||||||
} /* namespace rclcpp */
|
} /* namespace rclcpp */
|
||||||
|
|
||||||
#endif /* RCLCPP_RCLCPP_FUNCTION_TRAITS_HPP_ */
|
#endif /* RCLCPP_RCLCPP_FUNCTION_TRAITS_HPP_ */
|
||||||
|
|
|
@ -250,9 +250,17 @@ private:
|
||||||
template<
|
template<
|
||||||
typename ServiceT,
|
typename ServiceT,
|
||||||
typename FunctorT,
|
typename FunctorT,
|
||||||
typename std::enable_if<
|
std::size_t Arity = 2
|
||||||
function_traits<FunctorT>::arity == 2
|
>
|
||||||
>::type * = nullptr,
|
typename std::enable_if<
|
||||||
|
rclcpp::arity_comparator<Arity, FunctorT>::value,
|
||||||
|
typename rclcpp::service::Service<ServiceT>::SharedPtr
|
||||||
|
>::type
|
||||||
|
create_service_internal(
|
||||||
|
std::shared_ptr<rmw_node_t> node_handle,
|
||||||
|
rmw_service_t * service_handle,
|
||||||
|
const std::string & service_name,
|
||||||
|
FunctorT callback,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<
|
std::is_same<
|
||||||
typename function_traits<FunctorT>::template argument_type<0>,
|
typename function_traits<FunctorT>::template argument_type<0>,
|
||||||
|
@ -264,14 +272,7 @@ private:
|
||||||
typename function_traits<FunctorT>::template argument_type<1>,
|
typename function_traits<FunctorT>::template argument_type<1>,
|
||||||
typename std::shared_ptr<typename ServiceT::Response>
|
typename std::shared_ptr<typename ServiceT::Response>
|
||||||
>::value
|
>::value
|
||||||
>::type * = nullptr
|
>::type * = nullptr)
|
||||||
>
|
|
||||||
typename rclcpp::service::Service<ServiceT>::SharedPtr
|
|
||||||
create_service_internal(
|
|
||||||
std::shared_ptr<rmw_node_t> node_handle,
|
|
||||||
rmw_service_t * service_handle,
|
|
||||||
const std::string & service_name,
|
|
||||||
FunctorT callback)
|
|
||||||
{
|
{
|
||||||
typename rclcpp::service::Service<ServiceT>::CallbackType callback_without_header =
|
typename rclcpp::service::Service<ServiceT>::CallbackType callback_without_header =
|
||||||
callback;
|
callback;
|
||||||
|
@ -282,9 +283,17 @@ private:
|
||||||
template<
|
template<
|
||||||
typename ServiceT,
|
typename ServiceT,
|
||||||
typename FunctorT,
|
typename FunctorT,
|
||||||
typename std::enable_if<
|
std::size_t Arity = 3
|
||||||
function_traits<FunctorT>::arity == 3
|
>
|
||||||
>::type * = nullptr,
|
typename std::enable_if<
|
||||||
|
arity_comparator<Arity, FunctorT>::value,
|
||||||
|
typename rclcpp::service::Service<ServiceT>::SharedPtr
|
||||||
|
>::type
|
||||||
|
create_service_internal(
|
||||||
|
std::shared_ptr<rmw_node_t> node_handle,
|
||||||
|
rmw_service_t * service_handle,
|
||||||
|
const std::string & service_name,
|
||||||
|
FunctorT callback,
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<
|
std::is_same<
|
||||||
typename function_traits<FunctorT>::template argument_type<0>,
|
typename function_traits<FunctorT>::template argument_type<0>,
|
||||||
|
@ -296,35 +305,14 @@ private:
|
||||||
typename function_traits<FunctorT>::template argument_type<1>,
|
typename function_traits<FunctorT>::template argument_type<1>,
|
||||||
typename std::shared_ptr<typename ServiceT::Request>
|
typename std::shared_ptr<typename ServiceT::Request>
|
||||||
>::value
|
>::value
|
||||||
>::type * = nullptr
|
>::type * = nullptr,
|
||||||
/*
|
|
||||||
TODO(esteve): reenable this block of code when VS2015 gets better support
|
|
||||||
for SFINAE and remove the static_assert from the body of this method. For
|
|
||||||
more info about the current support for SFINAE in VS2015 RC:
|
|
||||||
|
|
||||||
http://blogs.msdn.com/b/vcblog/archive/2015/04/29/c-11-14-17-features-in-vs-2015-rc.aspx
|
|
||||||
,
|
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
std::is_same<
|
std::is_same<
|
||||||
typename function_traits<FunctorT>::template argument_type<2>,
|
typename function_traits<FunctorT>::template argument_type<2>,
|
||||||
typename std::shared_ptr<typename ServiceT::Response>
|
typename std::shared_ptr<typename ServiceT::Response>
|
||||||
>::value
|
>::value
|
||||||
>::type * = nullptr
|
>::type * = nullptr)
|
||||||
*/
|
|
||||||
>
|
|
||||||
typename rclcpp::service::Service<ServiceT>::SharedPtr
|
|
||||||
create_service_internal(
|
|
||||||
std::shared_ptr<rmw_node_t> node_handle,
|
|
||||||
rmw_service_t * service_handle,
|
|
||||||
const std::string & service_name,
|
|
||||||
FunctorT callback)
|
|
||||||
{
|
{
|
||||||
static_assert(
|
|
||||||
std::is_same<
|
|
||||||
typename function_traits<FunctorT>::template argument_type<2>,
|
|
||||||
typename std::shared_ptr<typename ServiceT::Response>
|
|
||||||
>::value, "Third argument must be of type std::shared_ptr<ServiceT::Response>");
|
|
||||||
|
|
||||||
typename rclcpp::service::Service<ServiceT>::CallbackWithHeaderType callback_with_header =
|
typename rclcpp::service::Service<ServiceT>::CallbackWithHeaderType callback_with_header =
|
||||||
callback;
|
callback;
|
||||||
return service::Service<ServiceT>::make_shared(
|
return service::Service<ServiceT>::make_shared(
|
||||||
|
|
328
rclcpp/test/test_function_traits.cpp
Normal file
328
rclcpp/test/test_function_traits.cpp
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
// Copyright 2015 Open Source Robotics Foundation, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <rclcpp/function_traits.hpp>
|
||||||
|
|
||||||
|
int func_no_args()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_one_int(int)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_two_ints(int, int)
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int func_one_int_one_char(int, char)
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FunctionObjectNoArgs
|
||||||
|
{
|
||||||
|
int operator()() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FunctionObjectOneInt
|
||||||
|
{
|
||||||
|
int operator()(int) const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FunctionObjectTwoInts
|
||||||
|
{
|
||||||
|
int operator()(int, int) const
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FunctionObjectOneIntOneChar
|
||||||
|
{
|
||||||
|
int operator()(int, char) const
|
||||||
|
{
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctorT,
|
||||||
|
std::size_t Arity = 1
|
||||||
|
>
|
||||||
|
typename std::enable_if<rclcpp::arity_comparator<Arity, FunctorT>::value, int>::type
|
||||||
|
func_accept_callback(FunctorT callback,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
typename rclcpp::function_traits<FunctorT>::template argument_type<0>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int a = 4;
|
||||||
|
return callback(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctorT,
|
||||||
|
std::size_t Arity = 2
|
||||||
|
>
|
||||||
|
typename std::enable_if<rclcpp::arity_comparator<Arity, FunctorT>::value, int>::type
|
||||||
|
func_accept_callback(FunctorT callback,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
typename rclcpp::function_traits<FunctorT>::template argument_type<0>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
typename rclcpp::function_traits<FunctorT>::template argument_type<1>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr)
|
||||||
|
{
|
||||||
|
int a = 5;
|
||||||
|
int b = 6;
|
||||||
|
return callback(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename FunctorT,
|
||||||
|
std::size_t Arity = 2
|
||||||
|
>
|
||||||
|
typename std::enable_if<rclcpp::arity_comparator<Arity, FunctorT>::value, int>::type
|
||||||
|
func_accept_callback(FunctorT callback,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
typename rclcpp::function_traits<FunctorT>::template argument_type<0>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr,
|
||||||
|
typename std::enable_if<
|
||||||
|
std::is_same<
|
||||||
|
char,
|
||||||
|
typename rclcpp::function_traits<FunctorT>::template argument_type<1>
|
||||||
|
>::value
|
||||||
|
>::type * = nullptr)
|
||||||
|
{
|
||||||
|
int a = 7;
|
||||||
|
char b = 8;
|
||||||
|
return callback(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tests that funcion_traits calculates arity of several functors.
|
||||||
|
*/
|
||||||
|
TEST(TestFunctionTraits, arity) {
|
||||||
|
// Test regular functions
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(func_no_args)>::arity == 0,
|
||||||
|
"Functor does not accept arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(func_one_int)>::arity == 1,
|
||||||
|
"Functor only accepts one argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(func_two_ints)>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(func_one_int_one_char)>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
|
||||||
|
// Test lambdas
|
||||||
|
auto lambda_no_args = []() {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto lambda_one_int = [](int) {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto lambda_two_ints = [](int, int) {
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto lambda_one_int_one_char = [](int, char) {
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(lambda_no_args)>::arity == 0,
|
||||||
|
"Functor does not accept arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(lambda_one_int)>::arity == 1,
|
||||||
|
"Functor only accepts one argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(lambda_two_ints)>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<decltype(lambda_one_int_one_char)>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
|
||||||
|
// Test objects that have a call operator
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<FunctionObjectNoArgs>::arity == 0,
|
||||||
|
"Functor does not accept arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<FunctionObjectOneInt>::arity == 1,
|
||||||
|
"Functor only accepts one argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<FunctionObjectTwoInts>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
rclcpp::function_traits<FunctionObjectOneIntOneChar>::arity == 2,
|
||||||
|
"Functor only accepts two arguments");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tests that funcion_traits deducts the type of the arguments of several functors.
|
||||||
|
*/
|
||||||
|
TEST(TestFunctionTraits, argument_types) {
|
||||||
|
// Test regular functions
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(func_one_int)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(func_two_ints)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(func_two_ints)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts an int as second argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(func_one_int_one_char)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
char,
|
||||||
|
rclcpp::function_traits<decltype(func_one_int_one_char)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a char as second argument");
|
||||||
|
|
||||||
|
// Test lambdas
|
||||||
|
auto lambda_one_int = [](int) {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto lambda_two_ints = [](int, int) {
|
||||||
|
return 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto lambda_one_int_one_char = [](int, char) {
|
||||||
|
return 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(lambda_one_int)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(lambda_two_ints)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(lambda_two_ints)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts an int as second argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<decltype(lambda_one_int_one_char)>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
char,
|
||||||
|
rclcpp::function_traits<decltype(lambda_one_int_one_char)>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a char as second argument");
|
||||||
|
|
||||||
|
// Test objects that have a call operator
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<FunctionObjectOneInt>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<FunctionObjectTwoInts>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<FunctionObjectTwoInts>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts an int as second argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
int,
|
||||||
|
rclcpp::function_traits<FunctionObjectOneIntOneChar>::template argument_type<0>
|
||||||
|
>::value, "Functor accepts an int as first argument");
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same<
|
||||||
|
char,
|
||||||
|
rclcpp::function_traits<FunctionObjectOneIntOneChar>::template argument_type<1>
|
||||||
|
>::value, "Functor accepts a char as second argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tests that functions are matched via SFINAE.
|
||||||
|
*/
|
||||||
|
TEST(TestFunctionTraits, sfinae_match) {
|
||||||
|
EXPECT_EQ(1, func_accept_callback(func_one_int));
|
||||||
|
|
||||||
|
EXPECT_EQ(2, func_accept_callback(func_two_ints));
|
||||||
|
|
||||||
|
EXPECT_EQ(3, func_accept_callback(func_one_int_one_char));
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue