All pastes #498527 Raw Edit

Untitled

public text v1 · immutable
·published 2007-05-20 14:26 UTC
rendered paste body
typedef std::map<int, AnyDataP> argMap;

template<typename... Args> struct Caster;
template<> 
struct Caster<> 
{
    static const int something = 0;
    int setup( const argMap &m, int arg ) { return arg; }
};

template<typename T>
void assignThing( T **thing, void *with )
{
    *thing = (T *)with;
}

template<typename T>
void assignThing( T *thing, void *with )
{
}


template<typename T, typename... Args>
struct Caster<T, Args...>
{
    typedef
      typename boost::mpl::if_< 
        boost::is_reference<T>, 
        typename boost::add_pointer<typename boost::remove_reference<T>::type >::type, 
        T >::type NonRefType; 
    
    NonRefType a;
    Caster<Args...> b;
    
    int setup( argMap &m, int arg = 0 )
    {
        if ( boost::is_reference<T>::value )
        {
            std::cout << "Reference argument" << std::endl;
            assignThing( &a, (m[arg]).asVoid() );
        } else
        {
            std::cout << "Fetching arg #" << arg << std::endl;
            if ( !m.count( arg ) )
                throw std::string( "Wrong number of args" );
            a = (m[arg]).getValue<NonRefType>();
            std::cout << "Left the fetching function, set to " << TypeName<NonRefType>::getValue() << " - " << a << std::endl;
        }
        
        return b.setup( m, ++arg );
    } 
};


template<typename... Args> struct argsToAnyDataP;
template<> struct argsToAnyDataP<> 
{ 
    static const int num = 0;
    static const int deepest = 0;
    static int argGetter( int n, argMap &m ) { return 0; }
};

template<typename T, typename... Args>
struct argsToAnyDataP<T, Args...>
{
    static int argGetter( int n, argMap &m, 
                           const T& arg, 
                           const Args&... args ) 
    {
        argsToAnyDataP<Args...>::argGetter( n+1, m, args... );
        m[ n ] = arg;
    }
};

template<typename... Args>
AnyData AnyData::operator()(const Args&... args)
{
    typedef AnyData (*fptr)(void *, argMap &);
            
    fptr f = (fptr)callerFunc;
    argMap m;
    argsToAnyDataP<Args...>::argGetter( 0, m, args... );
    
    
    //std::cout << "I am here.." << std::endl;
    return f( getValue<void *>(), m );
}

template<typename RET, typename... Args>
AnyData theCaller( void * funcToCall, argMap &m ) //, const Args... a )
{
    std::cout << "I am in the caller." << sizeof...( Args) << std::endl;
    Caster<Args...> them;
    if ( them.setup( m ) != m.size() )
        throw std::string("Wrong number of arguments");
    typedef RET (*fptr)( Caster<Args...> );
    std::cout << "On my way out.." << std::endl;
    return AnyData( ((fptr)funcToCall)( them ) );
}

template<typename... Args>
void AnyData::setCallerFunc( AnyData (*p)(const Args...) )
{
    callerFunc = (void *)p;
}

template<typename RET, typename... Args>
AnyData &AnyData::operator=( RET (*assign)( Args... ) )
{
    typedef __typeof(assign) funcp;
    
    //Args...;
    
    std::cout << "Assigning function pointer..." << std::endl;
    funcArgs = functionGetter<Args...>();
    setCallerFunc( &theCaller<RET, Args...> );
    //theCaller<Args...>( 1, 2 );
    
    delete data;
    data = new Storage<funcp>( assign );
    
    return *this;
}