1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include <iostream>
#include <vector>
#include <unordered_map>
#include <functional>
#include <iomanip>
#ifdef __cpp_lib_experimental_any
#include <experimental/any>
namespace stx = std::experimental ;
#else
#include <boost/any.hpp>
namespace stx = boost ;
#endif // __cpp_lib_experimental_any
using map_type = std::unordered_map< std::string, std::function< stx::any( const std::vector<stx::any>& ) > > ;
stx::any call_it( const std::string& fn_name, const std::vector<stx::any>& args, const map_type& map ) // may throw
{
const auto iter = map.find(fn_name) ;
if( iter != map.end() ) return iter->second(args) ;
else return {} ;
}
std::string foo( int a, double b, short c )
{ std::cout << "std::string foo(int,double,short) => " ; return std::to_string(a+b+c) ; }
stx::any foo_wrapper( const std::vector<stx::any>& args ) // may throw
{
if( args.size() != 3 ) throw std::invalid_argument( "invalid number of args" ) ;
return foo( stx::any_cast<int>(args[0]), stx::any_cast<double>(args[1]), stx::any_cast<short>(args[2]) ) ;
}
struct A
{
std::size_t bar( int a, const std::string& b ) const
{ std::cout << "int A::bar(int,const std::string&) => " ; return a + b.size() + value ; }
int value = 234 ;
};
stx::any bar_wrapper( const std::vector<stx::any>& args ) // may throw
{
if( args.size() != 3 ) throw std::invalid_argument( "invalid number of args" ) ;
return stx::any_cast<A*>(args[0])->bar( stx::any_cast<int>(args[1]), stx::any_cast<std::string>(args[2]) );
}
int main()
{
map_type fn_map = { { "foo", foo_wrapper }, { "bar", bar_wrapper } } ;
auto result = call_it( "foo", { stx::any(12), stx::any(34.6), stx::any( short(7) ) }, fn_map ) ;
std::cout << "result: " << std::quoted( stx::any_cast<std::string>(result) ) << '\n' ;
A a ;
using namespace std::literals ;
result = call_it( "bar", { stx::any( std::addressof(a) ), stx::any(99), stx::any( "abcdefgh"s ) }, fn_map ) ;
std::cout << "result: " << stx::any_cast<std::size_t>(result) << '\n' ;
}
|