Re: Access Data Items In Ancestor Stack Frames Safely (Dr.Dobb's article)
A better version using virtual inheritance - pls. see below. So the
remaining issue is how to make the handling of variable arguments
generic(?)
=================================================
/*
* StackAccess.h
*
* Created on: May 31, 2013
* Author: frank
*/
#ifndef STACKACCESS_H_
#define STACKACCESS_H_
struct Nop
{
};
template <typename CALLER>
struct Func_Impl
{
CALLER * caller;
};
template <typename CALLER, typename RETURN_TYPE, typename... ARGS>
struct Func : virtual Func_Impl<CALLER>
{
virtual RETURN_TYPE exec_wrap(ARGS...) = 0;
virtual ~Func() { }
RETURN_TYPE exec(
CALLER * caller,
ARGS... args)
{
Func_Impl<CALLER>::caller = caller;
return exec_wrap(args...);
}
};
#endif /* STACKACCESS_H_ */
====================================================
/*
* main.cpp
*
* Created on: May 24, 2013
* Author: frank
*/
#include <iostream>
#include "StackAccess.h"
template <typename CALLER>
struct Func3_Impl : virtual Func_Impl<CALLER>
{
typedef Func3_Impl type;
void exec_impl(void)
{
std::cout << "Func3: entered" << std::endl;
std::cout << "caller->x = "
<< this->caller->x << std::endl;
std::cout << "caller->caller->x = "
<< this->caller->caller->x
<< std::endl;
}
};
template <class CALLER>
struct Func3 : public Func3_Impl<CALLER>,
public Func<
CALLER,
decltype(Func3_Impl<CALLER>().exec_impl())>
{
typedef decltype(Func3_Impl<CALLER>().exec_impl())
return_type;
inline return_type exec_wrap(void)
{
return this->exec_impl();
}
};
template <typename CALLER>
struct Func2_Impl : virtual Func_Impl<CALLER>
{
typedef Func2_Impl type;
int x;
int exec_impl (int p_val)
{
std::cout << "Func2: entered" << std::endl;
std::cout << "p_val = " << p_val << std::endl;
std::cout << "caller->x = " << this->caller->x << std::endl;
this->caller->x = 5;
Func3<type>().exec(this);
return 7;
}
};
template <class CALLER>
struct Func2 : public Func2_Impl<CALLER>,
public Func<
CALLER,
decltype(Func2_Impl<CALLER>().exec_impl(int())),
int> // TODO: how to handle variable arguments?
{
typedef decltype(Func2_Impl<CALLER>().exec_impl(int()))
return_type;
inline return_type exec_wrap(
int p_val) // TODO: want to be generic here too
{
return this->exec_impl(p_val);
}
};
template <typename CALLER>
struct Func1_Impl : virtual Func_Impl<CALLER>
{
typedef Func1_Impl type;
int x;
void exec_impl (void)
{
std::cout << "Func1: entered" << std::endl;
int getVal = Func2<type>().exec(this, 5);
std::cout << "Func2 returns #" << getVal
<< ", x = " << x << std::endl;
}
};
template <class CALLER>
struct Func1 : public Func1_Impl<CALLER>,
public Func<
CALLER,
decltype(Func1_Impl<CALLER>().exec_impl())>
{
public:
typedef decltype(Func1_Impl<CALLER>().exec_impl())
return_type;
inline return_type exec_wrap(void)
{
return this->exec_impl();
}
};
int main(
int argc,
char ** argv)
{
Nop nop;
Func1<Nop>().exec(&nop);
return 0;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]