Skip to content
This repository was archived by the owner on Sep 3, 2021. It is now read-only.
/ Callable_cpp Public archive

A c++ Callabe<return_type, args...> concept. It's 40 lines of the most gut-wrenchingly terse template metaprogramming you could imagine. I'm putting this out there hoping to spare someone a few hours of intense pain. Works with function pointers/references, lambdas, std::bind, functors...

Notifications You must be signed in to change notification settings

lenerdv2005/Callable_cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 

Repository files navigation

Callable_cpp

Description

A c++ Callable_c<return_type, args...> concept. It's 40 lines of the most gut-wrenchingly terse template metaprogramming you could imagine. I'm putting this out there hoping to spare someone a few hours of intense pain. Works with function pointers/references, lambdas, std::bind, functors... Essentially, if declval<Whatever_callable_type>()(Arg_types...) is well formed and returns Return_type, then Callable_c<Whatever_callable_type, Return_type, Arg_types...> is true.

Usage

Just include the header and use Callable_c: the arguments are

  • the type to check, omitted when declaring, say, a function parameter type, and necessary when using Callable_c as a boolean expression
  • the return type
  • the argument types

Examples

With regular functions:

int test_function(int) { return 0; }

std::cout << Callable_c<decltype(test_function), int(int)> << std::endl;   // outputs: true
std::cout << Callable_c<decltype(test_function), int(char)> << std::endl;  // outputs: true (implicitly convertible)
std::cout << Callable_c<decltype(test_function), int(void*)> << std::endl; // outputs: false (void* is not implicitly convertible to int)

With std::function

std::function<void(int, int, std::string)> test_std_function;

std::cout << Callable_c<decltype(test_std_function), void(int, int, std::string)> << std::endl; // outputs: true
std::cout << Callable_c<decltype(test_std_function), char(int, int, std::string)> << std::endl; // outputs: false (char is not equal to int)
std::cout << Callable_c<decltype(test_std_function), int(int, int, std::string)> << std::endl;  // outputs: false (void is not equal to int)

With std::bind

auto test_bind = std::bind(test_function, std::placeholders::_1);

std::cout << Callable_c<decltype(test_bind), int(int)> << std::endl;   // outputs: true
std::cout << Callable_c<decltype(test_bind), int(char)> << std::endl;  // outputs: true (implicitly convertible)
std::cout << Callable_c<decltype(test_bind), int(void*)> << std::endl; // outputs: false (void* is not implicitly convertible to int)

Differences from std::invocable

What changes is that Callable_c also checks the return type. Although, unlike with arguments, which are accepted even if the type is implicitly convertible, the return type has to be exactly the same. If you want, you can just go to what is now line 27 (I know for a fact that I will forget to update this readme) and switch the std::is_same_v with std::is_convertible_v. Or use any other condition.

About

A c++ Callabe<return_type, args...> concept. It's 40 lines of the most gut-wrenchingly terse template metaprogramming you could imagine. I'm putting this out there hoping to spare someone a few hours of intense pain. Works with function pointers/references, lambdas, std::bind, functors...

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages