293f3c2a   
   03704564   
   From: frank67x@googlemail.com   
      
   This is a strange monologue - sorry for that. But discussion with   
   others helped to clarify. At least found a way to deal with that for   
   "easy recursions" (see below). Now i can start to actually make use of   
   access to ancestor data. However, i had to recognize, that it there is   
   much more about it than i though. Because it's on the borderline   
   between compiler and interpreter. Because a function call hierarchy   
   not necessarily is deterministic at compile time.   
      
   ================= StackAccess.h =============================   
   #ifndef STACKACCESS_H_   
   #define STACKACCESS_H_   
      
   #include // std::mem_fn   
      
   struct Nop   
   {   
      
   };   
      
   template    
   struct Func_Impl   
   {   
    typedef CALLER caller_type;   
      
    caller_type * caller;   
      
   };   
      
   template    
   struct FuncCore : virtual Func_Impl   
   {   
    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::caller = caller;   
    return exec_wrap(args...);   
    }   
      
   };   
      
   template    
   struct Func : public IMPL,   
    public FuncCore   
   {   
    typedef typename FuncCore::return_type   
    return_type;   
      
    inline return_type exec_wrap(   
    ARGS... args)   
    {   
    return this->exec_impl(args...);   
    }   
      
   };   
   #endif /* STACKACCESS_H_ */   
   ================== main.cpp =================================   
   #include    
      
   #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(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    
   struct SortedList_Impl2 : virtual Func_Impl   
   {   
    typedef SortedList_Impl2 type;   
      
    BinaryTree* exec_recursive(   
    type * caller,   
    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 = type().exec_recursive(this, list, start,   
   mid-1);   
    BinaryTree *parent = new BinaryTree(list->data);   
    parent->left = leftChild;   
    list = list->next;   
    parent->right = type().exec_recursive(this, list, mid+1, end);   
    return parent;   
    }   
      
    BinaryTree* exec_impl(   
    ListNode *& list,   
    int start,   
    int end)   
    {   
    return exec_recursive(this, list, start, end);   
    }   
   };   
      
   template    
   struct SortedList_Impl1 : virtual Func_Impl   
   {   
    typedef SortedList_Impl1 type;   
      
    BinaryTree* exec_impl(   
    ListNode * head,   
    int n)   
    {   
    return Func, ListNode *&, int, int>().   
    exec(this, head, 0, n-1);   
    }   
   };   
   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, 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! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|