Re: Access Data Items In Ancestor Stack Frames Safely (Dr.Dobb's
article)
Here's the final version - pls. see below. But it's just an example.
Maybe for other algorithms it will be more usable.
best regards,
Frank
================= StackAccess.h ======================
#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 FuncCore : 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 ~FuncCore() { }
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 Func : public IMPL,
public FuncCore<IMPL, ARGS...>
{
typedef typename FuncCore<IMPL>::return_type
return_type;
inline return_type exec_wrap(
ARGS... args)
{
return this->exec_impl(args...);
}
};
#endif /* STACKACCESS_H_ */
================= main.cpp ===========================
#include <iostream>
#include "StackAccess.h"
struct ListNode
{
int data;
ListNode * next;
ListNode(int data)
: data(data),
next(NULL)
{ }
};
struct BinaryTree
{
int data;
BinaryTree * left;
BinaryTree * right;
BinaryTree()
: data(),
left(NULL),
right(NULL)
{ };
BinaryTree(int data)
: data(data),
left(NULL),
right(NULL)
{ }
void print()
{
bool child(false);
std::cout << data;
if (NULL == left && NULL == right)
{
return;
}
std::cout << "{";
if (NULL != left)
{
left->print();
child = true;
}
if (NULL != right)
{
if (child)
{
std::cout << ",";
}
right->print();
}
std::cout << "}";
}
};
BinaryTree* sortedListToBST(
ListNode *& list,
int start,
int end)
{
if (start > end) return NULL;
// same as (start+end)/2, avoids overflow
int mid = start + (end - start) / 2;
BinaryTree *leftChild = sortedListToBST(list, start, mid-1);
BinaryTree *parent = new BinaryTree(list->data);
parent->left = leftChild;
list = list->next;
parent->right = sortedListToBST(list, mid+1, end);
return parent;
}
BinaryTree* sortedListToBST(
ListNode *head,
int n)
{
return sortedListToBST(head, 0, n-1);
}
template <typename CALLER>
struct sortedListToBST_Impl : virtual Func_Impl<CALLER>
{
typedef sortedListToBST_Impl type;
int start;
int end;
int mid;
BinaryTree *new_node;
sortedListToBST_Impl()
: new_node(new BinaryTree())
{ };
sortedListToBST_Impl(
int p_start,
int p_end)
: start(p_start),
end(p_end),
mid(start + (end - start) / 2),
new_node((start > end)?NULL:new BinaryTree())
{ };
void exec_left(
type * caller,
ListNode *& current_element)
{
if (NULL == new_node) return;
type(start, mid-1).exec_left(this, current_element);
new_node->data = current_element->data;
current_element = current_element->next;
caller->new_node->left = new_node;
type(mid+1, end).exec_right(this, current_element);
};
void exec_right(
type * caller,
ListNode *& current_element)
{
if (NULL == new_node) return;
type(start, mid-1).exec_left(this, current_element);
new_node->data = current_element->data;
current_element = current_element->next;
caller->new_node->right = new_node;
type(mid+1, end).exec_right(this, current_element);
}
BinaryTree* exec_impl(
ListNode *& current_element,
int n)
{
start = 0;
end = n-1;
mid = start + (end - start) / 2;
type(start, mid-1).exec_left(this, current_element);
new_node->data = current_element->data;
current_element = current_element->next;
type(mid+1, end).exec_right(this, current_element);
return new_node;
}
};
int main(
int,
char**)
{
const int no = 30;
ListNode *root = NULL;
ListNode *inserter = NULL;
for (int i = 0; i < no; ++i)
{
ListNode *elem = new ListNode(i);
if (NULL == inserter)
{
root = elem;
}
else
{
inserter->next = elem;
}
inserter = elem;
}
{
BinaryTree *tree = sortedListToBST(root, no);
tree->print();
std::cout << std::endl;
}
{
Nop nop;
BinaryTree * tree = Func<sortedListToBST_Impl<Nop>, ListNode*,
int>().
exec(&nop, root, no);
tree->print();
std::cout << std::endl;
}
return 0;
}
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]