Generic function bind() with Boost - c++

I have some C-style functions that return 0 to indicate success, and != 0 on error.
I'd like to "wrap" them into void functions that throw instead of returning a value.
I have written this helper:
void checkStatus(int status) {
if (status != 0)
// throw an error object
}
Then, to wrap a determinate function int tilt(float degrees), I use boost::bind:
function<void(float)> ntilt = bind(checkStatus, bind(tilt, _1));
ntilt(30); // this will call checkStatus(tilt(30))
And it works great. But I'd like to have a dedicate wrapper function, so I can just do:
function<void(float)> ntilt = wrap(tilt);
ntilt(30); // this will call checkStatus(tilt(30))
It should work for any function/signature that returns an int.
What would be the best way to do it using Boost?

You could create several overloads to handle the different amount of parameters that your wrapped functions might take:
// handles 1 parameter functions
template<typename Ret, typename T0>
function<void(T0)> wrap(Ret (*fun)(T0)) {
return bind(checkStatus, bind(fun, _1));
}
// handles 2 parameters functions
template<typename Ret, typename T0, typename T1>
function<void(T0, T1)> wrap(Ret (*fun)(T0, T1)) {
return bind(checkStatus, bind(fun, _1, _2));
}
// ... add more
Here's a C++11 implementation. You could avoid some stuff if you didn't want an std::function, but well, it works:
#include <functional>
#include <stdexcept>
template<typename Ret, typename... Args>
struct wrapper {
typedef Ret (*function_type)(Args...);
void operator()(Args&&... args) {
if(fun(std::forward<Args>(args)...) != 0)
throw std::runtime_error("Error");
}
function_type fun;
};
template<typename Ret, typename... Ts>
std::function<void(Ts...)> wrap(Ret (*fun)(Ts...)) {
return std::function<void(Ts...)>(wrapper<Ret, Ts...>{fun});
}
Here is a live demo.

Related

How to use std::bind with the standard library and save the return type?

I'm working on a class that schedules functions by binding them in a queue like this:
std::queue <void()> q;
template<typename R,typename... ArgsT>
void
schedule(R& fn, ArgsT&... args)
{
q.push(std::bind(fn, std::forward<ArgsT>(args)...) );
};
template<typename R,typename... ArgsT>
void
schedule(R&& fn, ArgsT&&... args)
{
q.push(std::bind(fn, std::forward<ArgsT>(args)...) );
};
As you see I made the type in the queue void() to make it hold any type of function objects but now I can't get the return when I execute it. What should I do to solve this?
Note: I don't want to use an external library like boost and I don't know what kind of function the user will pass it.
Note: I don't want to use an external library like boost and I don't
know what's the kind of function the user will pass it.
What I usually do in this case is I use a base class (from Command pattern) in my queue, and then have two implementations, the one wrapping the bind, and the other (also wrapping the bind) exposing a function that allows getting the return value.
Here is an example of the returning specialization (at last):
#include <iostream>
#include <functional>
#include <memory>
struct ACmd
{
virtual void exec() = 0;
virtual ~ACmd(){}
};
template <class F>
struct Cmd;
template <class R, class ... Args>
struct Cmd<R(Args...)> : ACmd
{
R result_;
std::function<R()> func_;
template <class F>
Cmd(F&& func, Args&&... args): result_(), func_()
{
auto f = std::bind(std::forward<F>(func), std::forward<Args>(args)...);
func_ = [f](){
return f();
};
}
virtual void exec(){
result_ = func_();
}
const R& getResult() const {return result_;}
};
// Make function for convenience, could return by value or ptr -
// - your choice
template <class R, class F, class ...Args>
Cmd<R(Args...)>* cmd(F&& func, Args&&... args)
{
return new Cmd<R(Args...)>(func, std::forward<Args>(args)...);
}
//... And overload for void...
int foo(int arg) {
return arg;
}
int main() {
auto x = cmd<int>(foo, 10);
x->exec();
std::cout << x->getResult() << std::endl;
return 0;
}
The result of the execution of each element in the queue, it is void, you have already defined it as such. If the functions passed in are required to return a value, then you would need to limit the type(s) returned to a fixed type, use utilities such as std::any, std::variant or some covariant types (possible with a std::unique_ptr or std::shared_ptr).
The simplest is to fix the return type (at compile time);
template <typename R>
using MQ = std::queue<std::function<R()>>;
MQ<int> q;
See the sample below.
The queue declaration needs to be a queue of objects, such as std::function objects. The return value from a bind can be assigned to a function and then used as expected.
std::function is a polymorphic function wrapper, it implements type erasure patterns akin to any, but is specifically designed for functions and other callable objects.
By way of example;
template <typename R>
using MQ = std::queue<std::function<R()>>;
MQ<int> q;
template<typename R,typename... ArgsT>
void
schedule(R&& fn, ArgsT&&... args)
{
q.push(std::bind(std::forward<R>(fn), std::forward<ArgsT>(args)...) );
};
int main()
{
schedule([](int a) { std::cout << "function called" << std::endl; return a; }, 42);
std::cout << q.front()() << std::endl;
}

Template function accepting callable functors with X parameters

I'm writing a hosted C++ program that runs user-written C-code compiled on the fly. It's absolutely vital that certain typical exceptions are caught from the C-code and processed/ignored.
To do this, I'm calling the C code from within a structured exception handling block. Due to the nature and semantics of this block (and where it's called from), I've separated the actual calling to it's own function:
template <typename ret_type, class func>
static ret_type Cstate::RunProtectedCode(func function) {
ret_type ret = 0;
__try {
ret = function();
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
Which works nicely as it should like so:
RunProtectedCode<int>(entry);
But is it possible to shape this so i can call functions with variable amounts of parameters - maybe through some use of exotic functors (only requirement is obviously that it can't have a destructor)? I'm using MSVC++ 2010.
If you can use C++11 you can achive this with variadic tempaltes.
template <typename ret_type, class func, typename... Args>
static ret_type Cstate::RunProtectedCode(func function, Args&&... args) {
ret_type ret = 0;
__try {
ret = function(std::forward<Args>(args)...);
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
And you can call it like
RunProtectedCode<int>(entry2, 1, 2);
RunProtectedCode<int>(entry3, 1, "a", 3);
You can simplify it (kind of) by using std::function instead.
template <class func, typename... Args>
static
typename func::result_type Cstate::RunProtectedCode(func function, Args&&... args) {
typename func::result_type ret = typename func::result_type();
__try {
ret = function(std::forward<Args>(args)...);
}
__except(ExceptionHandler(GetExceptionCode(), ExceptionStatus::CSubsystem)) {
fprintf(stderr, "First chance exception in C-code.\n");
}
return ret;
}
And you can call it like
std::function<int(int,int,int)> entry_f = entry;
RunProtectedCode(entry_f,1,2,3);
You can bind all arguments to your function making it effectively 0-ary functor, e.g. using std::bind (available in VC2010) or boost::bind (I prefer this one because VC implementation contains broken std::cref). Binding can be done in overloaded function before passing to RunProtectedCode, e.g. something like this:
template<typename R>
R(*f)() wrap(R(*f)())
{
return f;
}
template<typename R, typename A>
boost::function<R(A)> wrap(R(*f)(), A a)
{
return boost::bind(f, a);
}
template<typename R, typename A1, typename A2>
boost::function<R(A1, A2)> wrap(R(*f)(), A1 a1, A2 a2)
{
return boost::bind(f, a1, a2);
}

How to implement an easy_bind() that automagically inserts implied placeholders?

I recently found this nifty snippet on the web - it allows you to bind without having to pass in explicit placeholders:
template <typename ReturnType, typename... Args>
std::function<ReturnType(Args...)>
easy_bind(ReturnType(*MemPtr)(Args...))
{
return [=]( Args... args ) -> ReturnType { return (*MemPtr)( args... ); };
}
This version works great with no args:
auto f1 = easy_bind( (std::string(*)(A&,A&))&Worker::MyFn );
later invoked with:
std::string s = f1( *p_a1, *p_a2 );
Question
Is it possible to modify the code to work with anything up to n args, filling 2-n (in this case) with placeholders? For example, this one should have one placeholder:
auto f2 = easy_bind( (std::string(*)(A&,A&))&Worker::MyFn, *p_a1 );
later invoked with:
std::string s = f2( *p_a2 );
Bonus
Ultimately, it would nice to have something like this (which inserts no placeholders since it will use up the last one), but I don't think it's workable with this implementation (can't pattern-match the signature, I think):
auto f3 = easy_bind( f2, *p_a2 );
later invoked with:
std::string s = f3();
The bottom line is, it would be nice to have a version of bind where I don't need to put in placeholders - it would be quite useful in generic TMP code.
With the indices trick and the ability to tell std::bind about your own placeholder types, here's what I came up with:
#include <functional>
#include <type_traits>
#include <utility>
template<int I> struct placeholder{};
namespace std{
template<int I>
struct is_placeholder< ::placeholder<I>> : std::integral_constant<int, I>{};
} // std::
namespace detail{
template<std::size_t... Is, class F, class... Args>
auto easy_bind(indices<Is...>, F const& f, Args&&... args)
-> decltype(std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...))
{
return std::bind(f, std::forward<Args>(args)..., placeholder<Is + 1>{}...);
}
} // detail::
template<class R, class... FArgs, class... Args>
auto easy_bind(std::function<R(FArgs...)> const& f, Args&&... args)
-> decltype(detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...))
{
return detail::easy_bind(build_indices<sizeof...(FArgs) - sizeof...(Args)>{}, f, std::forward<Args>(args)...);
}
Live example.
Take note that I require the function argument to easy_bind to be either of type std::function, or convertible to it, so that I have a definite signature available.
This was troubling me a lot, since I had to bind a function in a situation when I did not know the arguments at the time. (A factory such as shown here How to implement serialization in C++)
For example (assume TSubClass::create is static)
template<typename TFactoryClass, typename TArgs...>
class Factory
{
public:
template<typename TSubClass>
void register(int id)
{
_map.insert(std::make_pair(id, std::bind(&TClass::create, /*how to give TArgs as placeholders??*/)));
}
}
instead I was able to replace the std::bind with a lambda expression without having to use all these helper classes!
template<typename TFactoryClass, typename TArgs...>
class Factory
{
public:
template<typename TSubClass>
void register(int id)
{
_map.insert(std::make_pair(id, [](TArgs... args) { TSubClass::create(args...); }));
}
}
as a bonus, you can also "bind" to constructors with this mechanism

Check at Compile-Time if Template Argument is void

I'm trying to wrap the Windows API functions to check errors when I so choose. As I found out in a previous SO question, I could use a template function to call the API function, and then call GetLastError() to retrieve any error it might have set. I could then pass this error to my Error class to let me know about it.
Here's the code for the template function:
template<typename TRet, typename... TArgs>
TRet Wrap(TRet(WINAPI *api)(TArgs...), TArgs... args)
{
TRet ret = api(args...);
//check for errors
return ret;
}
Using this I can have code as follows
int WINAPI someFunc (int param1, BOOL param2); //body not accessible
int main()
{
int ret = someFunc (5, true); //works normally
int ret2 = Wrap (someFunc, 5, true); //same as above, but I'll get a message if there's an error
}
This works wonderfully. However, there is one possible problem. Take the function
void WINAPI someFunc();
When subbing this into the template function, it looks as follows:
void Wrap(void(WINAPI *api)())
{
void ret = api(); //<-- ahem! Can't declare a variable of type void...
//check for errors
return ret; //<-- Can't return a value for void either
}
To get around this, I tried creating a version of the template where I replaced TRet with void. Unfortunately, this actually just causes an ambiguity of which one to use.
That aside, I tried using
if (strcmp (typeid (TRet).name(), "v") != 0) //typeid(void).name() == "v"
{
//do stuff with variable to return
}
else
{
//do stuff without returning anything
}
However, typeid is a runtime comparison, so the code still doesn't compile due to trying to declare a void variable, even if it never will.
Next, I tried using std::is_same <TRet, void>::value instead of typeid, but found out that it was a runtime comparison as well.
At this point, I don't know what to try next. Is there any possibility of getting the compiler to believe that I know what I'm doing will run fine? I don't mind attaching an extra argument to Wrap, but I couldn't really get anything out of that either.
I use Code::Blocks with GNU G++ 4.6.1, and Windows XP, as well as Windows 7. Thanks for any help, even if it is telling me that I'll have to end up just not using Wrap for functions that return void.
You can use a helper class to fine tune specializations:
template <typename F>
struct wrapper
{};
template <typename Res, typename... Args>
struct wrapper<Res(Args...)>
{
static Res wrap(Res (WINAPI *f)(Args...), Args&& args...)
{
Res r = f(std::forward<Args>(args)...);
// Blah blah
return r;
}
};
template <typename... Args>
struct wrapper<void(Args...)>
{
static void wrap(void (WINAPI *f)(Args...), Args&& args...)
{
f(std::forward<Args>(args)...);
// Blah blah
}
};
Now, you can write the wrapper:
template <typename Res, typename... Args>
Res Wrap(Res (WINAPI *f)(Args...), Args&& args...)
{
return wrapper<Res(Args...)>::wrap(f, std::forward<Args>(args)...);
}
Note that it works even when Res is void. You're allowed to return an expression returning void in a function returning void.
The correct type is deduced, as in Wrap(someFunc, 5, true), even for functions returning void.
To get around this, I tried creating a version of the template where I replaced TRet with void. Unfortunately, this actually just causes an ambiguity of which one to use.
That should work, I believe, because void is more specialised than TRet, but as you point out it doesn't. I may be missing something, but at any rate, it doesn't matter, you can prevent the TRet overload from being selected.
template<typename TFun, typename... TArgs>
auto Wrap(TFun api, TArgs&&... args) ->
typename std::enable_if<
!std::is_void<typename std::result_of<TFun(TArgs...)>::type>::value,
typename std::result_of<TFun(TArgs...)>::type
>::type
{
auto result = api(std::forward<TArgs&&>(args)...);
return result;
}
template<typename TFun, typename... TArgs>
auto Wrap(TFun api, TArgs&&... args) ->
typename std::enable_if<
std::is_void<typename std::result_of<TFun(TArgs...)>::type>::value,
typename std::result_of<TFun(TArgs...)>::type
>::type
{
api(std::forward<TArgs&&>(args)...);
}
void WINAPI f1()
{
}
void WINAPI f2(double)
{
}
int WINAPI f3()
{
return 0;
}
int WINAPI f4(double)
{
return 0;
}
int main() {
Wrap(f1);
Wrap(f2, 0);
return Wrap(f3) * Wrap(f4, 0);
}
Update: adjusted to allow for conversions from argument type to parameter type.
Promoting from comment to answer I understanding why specializing the return type as void didn't work (can't disambiguate on return types) but specializing with void and adding an additional parameter should work, what happened? You may have to invoke with explicit types.

Call function with parameters extracted from string

I'm looking at the following problem:
I get strings that are formatted like this:
functionname_parameter1_parameter2_parameter3
otherfunctionname_parameter1_parameter2
.
.
.
and i would like to call the function with the given parameters.
So let's say i have a function test:
void test(int x, float y, std::string z) {}
and i get a message:
test_5_2.0_abc
then i would like the function test to be automatically invoked like this:
test(5, 2.0, "abc");
Do you have any hints on how to accomplish this in C++?
Update: Updated stream_function to fix the argument-evaluation-order problem #Nawaz mentioned in the comments, and also removed the std::function for improved efficiency. Note that the evaluation-order fix only works for Clang, as GCC doesn't follow the standard here. An example for GCC, with manual order-enforcement, can be found here.
This is generally not that easy to accomplish. I wrote a little wrapper class around std::function once that extracts the arguments from a std::istream. Here's an example using C++11:
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <functional>
#include <stdexcept>
#include <type_traits>
// for proper evaluation of the stream extraction to the arguments
template<class R>
struct invoker{
R result;
template<class F, class... Args>
invoker(F&& f, Args&&... args)
: result(f(std::forward<Args>(args)...)) {}
};
template<>
struct invoker<void>{
template<class F, class... Args>
invoker(F&& f, Args&&... args)
{ f(std::forward<Args>(args)...); }
};
template<class F, class Sig>
struct stream_function_;
template<class F, class R, class... Args>
struct stream_function_<F, R(Args...)>{
stream_function_(F f)
: _f(f) {}
void operator()(std::istream& args, std::string* out_opt) const{
call(args, out_opt, std::is_void<R>());
}
private:
template<class T>
static T get(std::istream& args){
T t; // must be default constructible
if(!(args >> t)){
args.clear();
throw std::invalid_argument("invalid argument to stream_function");
}
return t;
}
// void return
void call(std::istream& args, std::string*, std::true_type) const{
invoker<void>{_f, get<Args>(args)...};
}
// non-void return
void call(std::istream& args, std::string* out_opt, std::false_type) const{
if(!out_opt) // no return wanted, redirect
return call(args, nullptr, std::true_type());
std::stringstream conv;
if(!(conv << invoker<R>{_f, get<Args>(args)...}.result))
throw std::runtime_error("bad return in stream_function");
*out_opt = conv.str();
}
F _f;
};
template<class Sig, class F>
stream_function_<F, Sig> stream_function(F f){ return {f}; }
typedef std::function<void(std::istream&, std::string*)> func_type;
typedef std::map<std::string, func_type> dict_type;
void print(){
std::cout << "print()\n";
}
int add(int a, int b){
return a + b;
}
int sub(int a, int b){
return a - b;
}
int main(){
dict_type func_dict;
func_dict["print"] = stream_function<void()>(print);
func_dict["add"] = stream_function<int(int,int)>(add);
func_dict["sub"] = stream_function<int(int,int)>(sub);
for(;;){
std::cout << "Which function should be called?\n";
std::string tmp;
std::cin >> tmp;
auto it = func_dict.find(tmp);
if(it == func_dict.end()){
std::cout << "Invalid function '" << tmp << "'\n";
continue;
}
tmp.clear();
try{
it->second(std::cin, &tmp);
}catch(std::exception const& e){
std::cout << "Error: '" << e.what() << "'\n";
std::cin.ignore();
continue;
}
std::cout << "Result: " << (tmp.empty()? "none" : tmp) << '\n';
}
}
Compiles under Clang 3.3 and works as expected (small live example).
Which function should be called?
a
Invalid function 'a'
Which function should be called?
add
2
d
Error: 'invalid argument to stream_function'
Which function should be called?
add
2
3
Result: 5
Which function should be called?
add 2 6
Result: 8
Which function should be called?
add 2
6
Result: 8
Which function should be called?
sub 8 2
Result: 6
It was fun to hack that class together again, hope you enjoy. Note that you need to modify the code a little to work for your example, since C++ IOstreams have whitespace as delimiter, so you'd need to replace all underscores in your message with spaces. Should be easy to do though, after that just construct a std::istringstream from your message:
std::istringstream input(message_without_underscores);
// call and pass 'input'
You pretty much can't, C++ doesn't have any kind of reflection on functions.
The question then is how close you can get. An interface like this is pretty plausible, if it would suit:
string message = "test_5_2.0_abc";
string function_name = up_to_first_underscore(message);
registered_functions[function_name](message);
Where registered_functions is a map<string,std::function<void,string>>, and you have to explicitly do something like:
registered_functions["test"] = make_registration(test);
for each function that can be called in this way.
make_registration would then be a fairly hairy template function that takes a function pointer as a parameter and returns a std::function object that when called splits the string into chunks, checks that there are the right number there, converts each one to the correct parameter type with a boost::lexical_cast, and finally calls the specified function. It would know the "correct type" from the template argument to make_registration -- to accept arbitrarily many parameters this would have to be a C++11 variadic template, but you can fake it with:
std::function<void,string> make_registration(void(*fn)(void));
template <typename T>
std::function<void,string> make_registration(void(*fn)(T));
template <typename T, U>
std::function<void,string> make_registration(void(*fn)(T, U));
// etc...
Dealing with overloads and optional parameters would add further complication.
Although I don't know anything about them, I expect that there are C++ support frameworks out there for SOAP or other RPC protocols, that might contain some relevant code.
What you are looking for is reflection. And it is not possible in C++. C++ is designed with speed in mind. If you require inspection of a library or code and then identify the types in it and invoke methods associated with those types (usually classes) then I am afraid it is not possible in C++.
For further reference you can refer to this thread.
How can I add reflection to a C++ application?
http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI
Why does C++ not have reflection?
You could parse the string, separate the arguments and send them to the function with no problem, but what you cannot do is reference the function with its name on a string, because the function doesn't have a name anymore at runtime.
You could have a if-else if chain that checks for the function name, and then parse the arguments and call the specific function.
I modified #Xeo's code to work with gcc properly, so it ensures the parameters are pulled in the right order. I'm only posting this since it took me a while to understand the original code and splice in the order-enforcement. Full credit should still go to #Xeo. If I find anything wrong with my implementation I'll come back and edit, but thus far in my testing I haven't seen any problems.
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <functional>
#include <stdexcept>
#include <type_traits>
#include <tuple>
template<class...> struct types{};
// for proper evaluation of the stream extraction to the arguments
template<class ReturnType>
struct invoker {
ReturnType result;
template<class Function, class... Args>
invoker(Function&& f, Args&&... args) {
result = f(std::forward<Args>(args)...);
}
};
template<>
struct invoker<void> {
template<class Function, class... Args>
invoker(Function&& f, Args&&... args) {
f(std::forward<Args>(args)...);
}
};
template<class Function, class Sig>
struct StreamFunction;
template<class Function, class ReturnType, class... Args>
struct StreamFunction<Function, ReturnType(Args...)>
{
StreamFunction(Function f)
: _f(f) {}
void operator()(std::istream& args, std::string* out_opt) const
{
call(args, out_opt, std::is_void<ReturnType>());
}
private:
template<class T>
static T get(std::istream& args)
{
T t; // must be default constructible
if(!(args >> t))
{
args.clear();
throw std::invalid_argument("invalid argument to stream_function");
}
return t;
}
//must be mutable due to const of the class
mutable std::istream* _args;
// void return
void call(std::istream& args, std::string*, std::true_type) const
{
_args = &args;
_voidcall(types<Args...>{});
}
template<class Head, class... Tail, class... Collected>
void _voidcall(types<Head, Tail...>, Collected... c) const
{
_voidcall<Tail...>(types<Tail...>{}, c..., get<Head>(*_args));
}
template<class... Collected>
void _voidcall(types<>, Collected... c) const
{
invoker<void> {_f, c...};
}
// non-void return
void call(std::istream& args, std::string* out_opt, std::false_type) const {
if(!out_opt) // no return wanted, redirect
return call(args, nullptr, std::true_type());
_args = &args;
std::stringstream conv;
if(!(conv << _call(types<Args...>{})))
throw std::runtime_error("bad return in stream_function");
*out_opt = conv.str();
}
template<class Head, class... Tail, class... Collected>
ReturnType _call(types<Head, Tail...>, Collected... c) const
{
return _call<Tail...>(types<Tail...>{}, c..., get<Head>(*_args));
}
template<class... Collected>
ReturnType _call(types<>, Collected... c) const
{
return invoker<ReturnType> {_f, c...} .result;
}
Function _f;
};
template<class Sig, class Function>
StreamFunction<Function, Sig> CreateStreamFunction(Function f)
{
return {f};
}
typedef std::function<void(std::istream&, std::string*)> StreamFunctionCallType;
typedef std::map<std::string, StreamFunctionCallType> StreamFunctionDictionary;
This also works with Visual Studio 2013, have not tried earlier versions.