While the C++ template based collections described in the preceding sections provides a very easy to use form of the collection concept, it does not allow for all the types of operations on aggregates that one frequently needs. For example, there is no way in which a member function of a element class to refer to the structure of the collection as a whole. This missing feature makes it difficult to write programs where one element object can refer to other elements in terms of the topology defined by the collection. To solve this problem there is a more elaborate (and more specialized) form of the collection class that has a special syntax.
Collection NameOfCollectionType: ParentCollection{
private:
< private data fields and method functions>
protected:
< protected data fields and method functions>
public:
< other public data fields and method functions>
MethodOfElement:
< data and functions that are added to each element>
};
The key points to understand are listed below.
To illustrate how the MethodOfELement field works, we will show how the pC++ compiler translates a collection into the correct template class. We will start with a simple ``hello world'' example. There are four parts to every pC++ program and they must be in the following order. First are the element class definitions. We will use a simple class E with one member function. Next, one must include the definition of the kernel with an include directive as shown below. Third are the definitions of the collections in the program. Last is the main program, which in pC++ version 1.0 is called Processor_Main().
#include "pcxx.h"
//*** element class definitions
class E{
public:
int e_data;
void sayHi(){ printf("hello"); }
};
//*** kernel.h must be included after the element classes are defined
#include "kernel.h"
//*** definitions of collections
Collection Set: SuperKernel{
int i;
Set(Distribution *T, Align *A);
MethodOfElement:
int j;
virtual void sayHi();
void hello(){ printf("\nfrom element %d", Ident); }
};
//*** collection constructor: has to be defined
//*** outside of the collection definition
Set::Set(Distribution *T, Align *A):SuperKernel(T,A)
{}
//*** the main program
Processor_Main(){
Processors P;
Distribution T(4,&P,BLOCK);
Align A(4,"[ALIGN(V[i],T[i])]");
Set<E> x(&T, &A);
x.sayHi();
x.hello();
}
The variable Ident is the unique element identifier that is assigned to each element by the SuperKernel. This program will print, up to a permutation of the last 4 lines,
hellohellohellohello from element 0 from element 3 from element 1 from element 2The collection Set in this example defines two new features that are added to each element. One is the integer field j and the other is the member function hello. Consequently, the user should view the action of the compiler in this case as defining a new class, which we shall call Element which is derived from the users original class E.
class Element: E{
public:
int Ident; // from SuperKernel MethodOfElement
Superkernel<Element> *ThisCollection;
... // additional SuperKernel Fields.
int j; // from Set MethodOfElement
void hello();
};
This new element class inherits all of the MethodOfElement fields
from all the collection in the inheritance chain of the Set collection.
A way to view this is that the MethodOfElement fields and member
functions form a wrapper around each collection element that allow the
element to references collection specific operators and data. The
ThisCollection pointer provides a way for the MethodOfElement
functions to refer to the TEClass object data that is local to the
thread containing the element object as a member of the local collection.
The Set collection is translated by the pC++ compiler to a template class of the form
template <class ELementType> TEClass Set: SuperKernel<ElementType>{
int i;
Set(Distribution *T, Align *A): SuperKernel(T,A){};
}
(Version 1.0 of the compiler does not actually generate an explicit
template. Instead, the compiler expand the collection into a new
class in a manner similar to the way the C++ compiler expands
templates. Version 2.0 will generate a template class as shown above.)
The main program is the same except that the collection object definition is translated to
Set<Element> x(&T, &A);