We chose to hide templates completely from our Volume API (Figure 2). Any user's program using our volume objects is likely to have function declarations or interface declarations in which the volume object is passed as an argument. For example, consider a function foo declared as foo(vlVolume * vol). If we do not hide the template from our volume API, the user will have to declare a templatized function like foo(vlVolume<DataType> * vol) which will eventually convert to multiple functions, one for each supported data type. This can be highly undesirable when the function is part of an interface.
To accomplish template hiding, we introduce a base class to the Volume Data Layout API which is non-templatized. A pointer of this base class is stored in the vlVolume class which at run time points to the correct data layout. In addition, the Volume API consists of functions which give information about the layout being used and the data type of the volume data. This information can be used to select the appropriate iterator for accessing the data.