[function] Anything to adapt a boost::function object?

Hi, I have an idea of something, and am not sure if Boost provides it. In short, I'd like an adapter object that "wraps" a boost::function object, and changes the interface such that all the N arguments are taken as strings, automatically converted (using lexical_cast?) to the proper types, and then invoke the boost::function object passsing in those parameters. For example, I envision something like this: #include "boost/function.hpp" #include <iostream> void func(int i, char c) { std::cout << "f called with " << i << " and " << c << std::endl; } int main() { boost::function<void(int, char)> f; f = &func; // I'm wanting something like this. boost::function_string_adapter str_f(f); // call func() but pass string args instead of int,char str_f("123", "x"); // invokes f(123i, 'x') } The magic is that boost::function knows the proper types, so the adapter could ask it to what type each string needs to be converted, then it could do a lexical_cast to get the value. My motivation for wanting this is to implement a "simple" command interpreter for a socket-based administrative interface. I pre-register a bunch of function objects, then whenever someone sends a command down the socket, it arrives as a string. The function object is looked up by name, and then the call-operator is invoked given the string arguments. Internally, the proper string-to-type converstions occur, and the boost::function is called with those values. (If the conversion fails, an exception would be perfectly reasonable.) Is this possible with anything in boost? Would the idea I show above be a good way to go, or might boost::function be the wrong approach? Thanks in advance! -- Chris

Chris Uzdavinis wrote:
Hi, I have an idea of something, and am not sure if Boost provides it. In short, I'd like an adapter object that "wraps" a boost::function object, and changes the interface such that all the N arguments are taken as strings, automatically converted (using lexical_cast?) to the proper types, and then invoke the boost::function object passsing in those parameters.
For example, I envision something like this:
#include "boost/function.hpp" #include <iostream>
void func(int i, char c) { std::cout << "f called with " << i << " and " << c << std::endl; }
int main() { boost::function<void(int, char)> f; f = &func;
// I'm wanting something like this. boost::function_string_adapter str_f(f);
// call func() but pass string args instead of int,char str_f("123", "x"); // invokes f(123i, 'x') }
The magic is that boost::function knows the proper types, so the adapter could ask it to what type each string needs to be converted, then it could do a lexical_cast to get the value.
Can it be done in a straightforward way? #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/lexical_cast.hpp> #include <string> #include <iostream> struct caster { std::string s; template<class T> operator T() const { return boost::lexical_cast<T>(s); } caster(std::string const& s) : s(s) {} caster(char const* s) : s(s) {} }; void f(int i, double d) { std::cout << i << char(0xa) << d << char(0xa); // sorry, my back-slash key does not work } int main() { boost::function<void(caster, caster)> g(f); g("123", "3.13"); }
My motivation for wanting this is to implement a "simple" command interpreter for a socket-based administrative interface. I pre-register a bunch of function objects, then whenever someone sends a command down the socket, it arrives as a string. The function object is looked up by name, and then the call-operator is invoked given the string arguments. Internally, the proper string-to-type converstions occur, and the boost::function is called with those values. (If the conversion fails, an exception would be perfectly reasonable.)
Don't you have to tokenize the input first? While doing so you might parse it as well.

Maxim Yegorushkin <maxim.yegorushkin@gmail.com> writes:
Can it be done in a straightforward way?
#include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/lexical_cast.hpp> #include <string> #include <iostream>
struct caster { std::string s; template<class T> operator T() const { return boost::lexical_cast<T>(s); } caster(std::string const& s) : s(s) {} caster(char const* s) : s(s) {} };
void f(int i, double d) { std::cout << i << char(0xa) << d << char(0xa); // sorry, my back-slash key does not work }
int main() { boost::function<void(caster, caster)> g(f); g("123", "3.13"); }
That's pretty clever. So simple--I like it! (I'll try this out and see how it goes.)
My motivation for wanting this is to implement a "simple" command interpreter for a socket-based administrative interface. I pre-register a bunch of function objects, then whenever someone sends a command down the socket, it arrives as a string. The function object is looked up by name, and then the call-operator is invoked given the string arguments. Internally, the proper string-to-type converstions occur, and the boost::function is called with those values. (If the conversion fails, an exception would be perfectly reasonable.)
Don't you have to tokenize the input first? While doing so you might parse it as well.
Actually, the data would be arriving in a CORBA sequence of strings, which is similar to a vector. Thus, the args would already be "tokenized". Thanks again for the idea! -- Chris
participants (2)
-
Chris Uzdavinis
-
Maxim Yegorushkin