Previous: Examples Up: Examples Next: Linked List with global pointers

Linked List

Suppose we need to transfer a linked list between processor objects. The type is defined much like the linked list used in Chapter , except that no sync links are used.


struct ListNode {
  ListNode* next;
  int data;
  ListNode (int d) { data = d; next = 0;}
  ListNode() {}  // Default constructor to be called before {\tt operator>>}
  friend CCVoid& operator<<(CCVoid&,const ListNode&);
  friend CCVoid& operator>>(CCVoid&,ListNode&);
};

struct List { int size; ListNode* head; ListNode* tail;

List() { head = 0; tail = 0; size = 0; } // Called before {\tt operator>>} void append (ListNode* nn) { if (tail!=0) { tail->next = nn; tail = nn; } else { head = nn; tail = nn; } size++; } void remove();

friend CCVoid& operator<<(CCVoid&,const List&); friend CCVoid& operator>>(CCVoid&,List&); };

We might write the transfer functions as follows


CCVoid& operator<<(CCVoid& v,const ListNode& in)
{
  v << in.data; return v;
}

CCVoid& operator>>(CCVoid& v,ListNode& out) { v >> out.data; return v; }

CCVoid& operator<<(CCVoid& v,const List& in) { v << in.size; ListNode* temp = in.head; for (int i=0; i<in.size; i++) { v << *temp; temp = temp->next; } return v; }

CCVoid& operator>>(CCVoid& v,List& out) { // Assume head==0 and tail==0 and size==0 int size; v >> size; for (int i=0; i<size; i++) { ListNode* new_node = new ListNode(); v >> *new_node; out.append(new_node); } return v; }

We send the ListNode structures in head to tail order, and reconstruct the list in the remote processor object. The ListNode structures are just integers here, but in general they could be arbitrarily complex data structures. Note that the unpacking function for the list assumes that head==0 && tail==0 && size==0, i.e., that the default constructor has been called for the object into which the data is being unpacked.

paolo@cs.caltech.edu