Handles and Templates

Sometimes you might want to use a template class that would inherit Standard_Transient (or its subclass). As you need to pair it with a handle counterpart (which would have to inherit respective Handle_Standard_Transient subclass), you can't do this with the DEFINE_STANDARD_HANDLE macro directly. This post explains how you could do this.

ACIS and Parasolid formats (like IGES or STEP for instance) represent a file as a list of entities that have id's. To represent an ACIS or a Parasolid file in memory, the Base_FileModel class is used. It basically provides access to the file header and manages a set of entities where an entity is of course specific to each format. To ease sharing Base_FileModel it should be manipulated by handle (i.e. inherit Standard_Transient). Here is how this is done:

template class Base_FileModel : public Base_Transient

//! Defines a type to index entities.
/*! @todo It must be signed (e.g. to address -1 in ACIS. Should it be consistent with size_t (for 64bit port)?
typedef int Index_t;

//! Defines an entity type.
/*! Equals to the template parameter.*/
typedef En Entity_t;

//! Returns a number of entities.
/*! An empty model returns 0.*/
size_t NbEntities() const { return myRevEntMap.Size() - 1; }

//! Adds an entity.
/*! Returns a rank number with which \a theEntity has been added into the model. By
default, a new rank number is maximum rank number + 1.
Null entities are ignored.

This method is not thread-safe.

\sa Bind().
Index_t Add (const Entity_t& theEntity)
Index_t aRank = myNullRank;
if (!theEntity.IsNull()) {
aRank = myEntVec.Size() + myNullRank;
Bind (aRank, theEntity);
return aRank;

//! Constructor.
/*! \a theNullRank defines a null rank used to designate a null entity (e.g. 0 for
Parasolid or -1 for ACIS).
Base_FileModel (const FileHeader_t& theHeader, const Index_t theNullRank) :
myHeader (theHeader), myNullRank (theNullRank)
const Entity_t aNull;
myEntVec.SetValue (Index (theNullRank), aNull);
myRevEntMap.Bind (aNull, theNullRank);


NCollection_Vector myEntVec;
NCollection_DataMap myRevEntMap;
const Index_t myNullRank;

Base_FileModel (const Base_FileModel&);
Base_FileModel& operator= (const Base_FileModel&);

Here is how a particular class (for ACIS) is defined:


class ACISBase_Model : public Base_FileModel

//! Constructor
/*! Creates a model with a new ACISBase_FileHeader.*/
ACISBase_Model() : Base_FileModel (
new ACISBase_FileHeader(), EntityNullRank) {}


Similarly in ACISBase_Model.cxx:


That's it !