Re: Access Data Items In Ancestor Stack Frames Safely (Dr.Dobb's article)
Clean-up / consolidation. But some renaming will be required. And
maybe possible to do some automatic type deduction of template
parameters in main.cpp?
==================================
/*
* StackAccess.h
*
* Created on: May 31, 2013
* Author: frank
*/
#ifndef STACKACCESS_H_
#define STACKACCESS_H_
#include <functional> // std::mem_fn
struct Nop
{
};
template <typename CALLER>
struct Func_Impl
{
typedef CALLER caller_type;
caller_type * caller;
};
template <typename IMPL, typename... ARGS>
struct Func : virtual Func_Impl<typename IMPL::caller_type>
{
typedef typename
decltype(std::mem_fn(&IMPL::exec_impl))::result_type return_type;
virtual return_type exec_wrap(ARGS...) = 0;
virtual ~Func() { }
return_type exec(
typename IMPL::caller_type * caller,
ARGS... args)
{
Func_Impl<typename IMPL::caller_type>::caller = caller;
return exec_wrap(args...);
}
};
template <typename IMPL, typename... ARGS>
struct MakeFunc : public IMPL,
public Func<IMPL, ARGS...>
{
typedef typename Func<IMPL>::return_type
return_type;
inline return_type exec_wrap(
ARGS... args)
{
return this->exec_impl(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 <typename CALLER>
struct Func2_Impl : virtual Func_Impl<CALLER>
{
typedef Func2_Impl type;
int x = 2;
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 = 3;
MakeFunc<Func3_Impl<type> >().exec(this);
return 7;
}
};
template <typename CALLER>
struct Func1_Impl : virtual Func_Impl<CALLER>
{
typedef Func1_Impl type;
int x = 1;
void exec_impl (void)
{
std::cout << "Func1: entered" << std::endl;
int getVal = MakeFunc<Func2_Impl<type>, int>().exec(this, 5);
std::cout << "Func2 returns #" << getVal
<< ", x = " << x << std::endl;
}
};
int main(
int argc,
char ** argv)
{
Nop nop;
MakeFunc<Func1_Impl<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! ]