Overview

The RoseObject class is the superclass of all STEP data objects. Some classes derived from RoseObject are shown below. Additional derived classes are created by the EXPRESS compiler.

  • RoseObject
    • RoseStructure
      • RoseDictionary
    • RoseUnion
    • RoseAggregate
      • RoseList
      • RoseBag
      • RoseSet
      • RoseArray
Predefined STEP Classes

The RoseObject class provides functions for manipulating any kind of STEP data. Applications that do not use specific C++ classes for each EXPRESS type will use these get<type>() and put<type>() functions. In addition, the RoseObject class defined functions that return the EXPRESS and C++ data dictionary information about each object, as well as other database utilities like move() and copy(). Refer to Working with STEP Data Objects for more information.

Operator new / pnew / pnewIn

<class> * operator new;
<class> * operator pnew;

<class> * operator pnewIn(
	RoseDesign * owner
	);

<class> * operator pnewIn(
	RoseDesignSection * owner
	);

You can use these operators to create new objects. In the C++ language, you use the new operator to implement storage allocation. In ROSE, the operators described below not only implement storage allocation, but also define additional semantics.

The new operator creates a non-persistent object — an object that is not owned by a design and will not be written to secondary storage.

Objects created by pnew and pnewIn are owned by a RoseDesign. The pnew operator creates an object and associates it with the design given by RoseInterface::design(). The pnewIn operator takes an explicit argument, which is usually a RoseDesign pointer, but may instead be a RoseDesignSection. The pnew and pnewIn operators are actually macros.

Given a cartesian point class, the following examples create some persistent and non-persistent point objects:

RoseDesign * design_1;
RoseDesign * design_2;
Point * pt;

ROSE.useDesign (design_1); /* set default design */

/* non-persistent point */
pt = new Point; 

/* point owned by default design (design_1) */
pt = pnew Point;

/* points owned by design_1 and design_2 */
pt = pnewIn (design_1) Point;
pt = pnewIn (design_2) Point;

/* point owned by design_2 in the default section */
pt = pnewIn (design_2->dflt_section()) Point;

See Also

Current Design; Creating Objects; RoseDesign::pnewInstance()

activate()

virtual void activate();

This function is called on every object by the ROSE library after the system has finished reading in a design file. You can redefine this function for a subclass to perform housekeeping tasks.

This function is only called when a design has been read in from secondary storage. Define a new default constructor if you want housekeeping tasks done whenever an object is created. This function is only called by the ROSE library and should never be called an application.

add_manager()

void add_manager(
	RoseManager * mgr
	);

An object can have a list of manager objects. The add_manager() function is used to append managers to the manager linked list. Each manager in the list must have a unique RoseManagerType identifier. This identifier is used to distinguish each manager from the others in the list. Refer to Manager Objects for particulars of using managers.

Given a SimpleManager class, we would add a new manager to an object using the following calls:

RoseObject * rose_obj;
SimpleManager * mgr = new SimpleManager;

rose_obj-> add_manager (mgr);  /* add to object */

See Also

Manager Objects; RoseManager; RoseObject::find_manager(); RoseObject::remove_manager();

address()

void * address();

Return the address of the object as it's most specific class. This is only for internal library use and should not be called by applications.

attributes()

ListOfRoseAttribute * attributes();

This function returns a list of RoseAttribute objects that describe each attribute of an object. This is equivalent to calling the RoseDomain::typeAttributes() function on the domain of an object. The list includes locally defined as well as inherited attributes. This list is used by the ROSE library, so it must not be modified.

The following example prints the name of all attributes of an object:

RoseObject * obj;
ListOfRoseAttribute * atts;
unsigned i, sz;

atts = obj-> attributes();
for (i=0, sz=atts->size(); i<sz; i++) {
    RoseAttribute * att = atts-> get (i);
    printf (Object contains an attribute called %s\n,
	     att-> name());
}

The following calls are equivalent:

atts = obj-> attributes();
atts = obj-> domain()-> typeAttributes();

See Also

Domains and Attributes; RoseDomain::typeAttributes(); RoseObject::domain(); RoseObject::getAttribute()

className()

char * className();

The className() function returns the name of the object's C++ class. This operation is a shorthand for calling the name() function on the RoseType description returned by the classType() function.

The following examples print the name of an object class.

RoseObject * object;
printf (Object is a %s class/n, object-> className());
printf (Object is a %s class/n, object-> classType()-> name());

See Also

C++ Type Information; RoseDomain::typeRoseType(); RoseObject::classType(); RoseType

classType()

RoseTypePtr& classType();

Each object is associated with a C++ class. The classType() function returns the run-time description of the C++ class. This class information is stored by a RoseType object.

The following examples print the name of an object class.

RoseObject * object;
printf (Object is a %s class/n, object-> classType()-> name());

See Also

C++ Type Information; RoseDomain::typeRoseType(); RoseType

copy()

RoseObject * copy(
	RoseDesign * new_design = NULL,
	unsigned max_depth = 0,
	RoseBoolean copy_externals = ROSE_FALSE
	);

The copy() function performs a deep copy on an object. If a design is not specified, the new objects will be copied into the same design. Copied objects will have new object identifiers (OIDs).

The depth parameter determines the level to which the system performs a copy of an object's descendents. The default depth is zero, which only copies the initial object. By default, the deep copy will not follow references into other design objects. Setting the copy_externals flag to true will expand the copy to objects not in the initial design object. The copies of external objects will be put in the new design.

The following example shows the use of the copy function to duplicate an object in another design:

Point * pt;
RoseObject * design_1;
RoseObject * design_2;

pt = pnewIn (design_1) Point;    /* create in design 1 */
pt-> copy (design_2);            /* make copy in design 2 */

See Also

Object Identifiers and References Between Designs; Moving and Copying Objects

design()

RoseDesign * design();

The design() function returns a pointer to an object's design. If an object is not owned by a design, the function will return NULL. Each RoseObject may belong to one design. Objects that are owned by a design, are written to secondary storage when the design is saved.

RoseObject * obj;

if (obj-> design())
      printf (Object belongs to %s\n, obj-> design()-> name());
else  printf (Object is non-persistent\n);

See Also

EXPRESS-defined C++ Objects; rose_move_to_design(); RoseObject::move()

design_section()

RoseDesignSection * design_section();

The design_section() function returns the RoseDesignSection that owns the object. If an object is not owned by a design, the function will return NULL. Each RoseObject may belong to one design section within one design. The design section determines how an object is written to secondary storage, and can be used for grouping data objects within a Part 21 file.

RoseObject * obj;
RoseDesignSection * section = obj-> design_section();

if (!section)
    printf (Non-Persistent Object\n);
else switch (section-> section_type()) {
case ROSE_SECTION_DATA:   printf (Data Object\n);  break;
case ROSE_SECTION_HEADER: printf (Header Object\n);  break;
case ROSE_SECTION_SYSTEM: printf (System Object\n);  break;
}

See Also

EXPRESS-defined C++ Objects; rose_move_to_section()

display()

void * display();

The display() function will recursively print the contents of a persistent object on stdout using the ROSE text working form. If the object is non-persistent, the function will print limited information. This function uses the RoseInterface traversal functions so it should not be used in an existing traversal.

The following fragment code fragment creates some cartesian point objects and then shows the use of the display() function to print the contents of a line object:

/* Create a point using the default constructor
 *  and use the update functions to set its values.
 */
Point * point1 = pnew Point;
point1->x (1.0);
point1->y (0.0);

/* Create points using a different constructor,
 *  that fills in the values in one step. */
Point * point2 = pnew Point (2.5, 4.0);
Point * point3 = pnew Point (5.0, 0.0);

/* Create and display a Line Object */
Line * line = pnew Line (point1, point2);
line-> display();

The terminal output from that call is as follows:

(<0-3> Line
	enda: (<0-0> Point
		x: 1
		y: 0)
	endb: (<0-1> Point
		x: 2.5
		y: 4))

See Also

RoseDesign::display()

domain()

RoseDomain * domain();

The domain() function returns the EXPRESS definition of an object. This class information is stored by a RoseDomain object. If the object is not persistent, this function returns the domain that the object would have if it were a persistent object.

The following example prints some information about an object:

RoseObject * object;
printf (Object's EXPRESS type is %s\n, object-> domain()->name());
printf (Object's C++ type is %s\n,     object-> classType()->name());

See Also

EXPRESS Data Dictionary

entity_comment()

char * entity_comment();

void entity_comment(
	const char * comstr
	);

The entity_comment() function gets and sets the comment which appears before an entity instance in a STEP physical file. If the object is not an entity (RoseStructure), the functions will not have any effect.

This can be particularly useful for documenting test data sets, especially when combined with the facilities that allow you to control the numbering and ordering of objects in a P21 file. When writing, the comment will always appear on the line before the entity instance, separated by a blank line from the previous instance.

When reading, comments are normally discarded and entity_comment() will just return null, but you can force the file processor to save them by adding the following lines to your application program:

#include <RoseP21Lex.h>  /* at the top of your file */

/* somewhere in your main, before you start reading files */
RoseP21Lex::comment_fn = rose_p21_read_and_preserve_comment;

After you do this, the entity_comment() function will return a string containing all comments seen between the end of the previous entity and the end of this entity are concatenated together as one string.

Do not use this facility to attempt to pass out of band data in a Part21 file. Most tools strip or ignore comments. Also, this facility only preserves comments in the data section of the file. Header section comments are not captured.

Given the following fragment:

calendar_date * cd;
local_time * lt;
cd-> entity_comment (This is my date instance);
lt-> entity_comment ( This is\n...my time instance\n );

When the instance is written out to a STEP Part 21 file, the comment would appear as follows:

/*This is my date instance*/
#58=CALENDAR_DATE(1993,17,7);

/* This is
...my time instance
*/
#59=LOCAL_TIME(13,47,28.0,#29);

Note the use of embedded newlines in the second example to spread the comment across multiple lines.

See Also

Customized File Handling

entity_id()

unsigned long entity_id();

void entity_id(
	unsigned long new_id
	);

The entity_id() function returns the entity identifiers (#nnn numbers) for objects that have been read in from a Part 21 physical file. These entity identifiers are only available for entity instances that are read from STEP physical files. This function will return zero for aggregates, selects, and any object read in from ROSE working form files.

The second form can be used to set the value if the identifier, although by default, entities are renumbered when written back out to disk. Refer to Customized File Handling for information on changing this behavior.

Given the following fragment of a STEP Part 21 file:

#57=DATE_AND_TIME(#58,#59);
#58=CALENDAR_DATE(1993,17,7);
#59=LOCAL_TIME(13,47,28.0,#29);

The entity_id() function would return 57 if called on the first instance, 58 if called on the second, and so on.

See Also

Entity Identifiers; Customized File Handling

findObjects()

RoseAggregate * findObjects(
	RoseAggregate * list_to_fill,
	unsigned max_depth = 0,
	RoseBoolean visit_externals = ROSE_TRUE
	);

RoseAggregate * findObjects(
	RoseDomain * domain,
	RoseAggregate * list_to_fill = NULL,
	unsigned max_depth = 0,
	RoseBoolean visit_externals = ROSE_TRUE
	);

The findObjects() functions search recursively through the attributes of a RoseObject, the attributes of those attributes, and so on, for objects which satisfy C++ class or ROSE domain criteria. The functions expect a RoseAggregate object to pass back pointers to the matching objects. Objects are appended to the aggregate, so it can be used to accumulate the results of several searches. If no aggregate is passed in, a ListOfRoseObject will be created by the function. It is the programmer's responsibility to free this object when it is no longer needed.

Both functions examine the type of the return aggregate and return objects matching that type (or its subtypes). For example, if a function were passed a ListOfPoint, only objects of the C++ class Point or its subclasses would be put into the list. The second version also takes a RoseDomain object. In this case, objects must be an instance of the EXPRESS type given by the domain as well as the C++ class restrictions implied by the return list. The domain should be at least as specific as the C++ class constraints.

The max_depth parameter determines the maximum depth of the search. For example, if you want to restrict the search to the initial object and that object's children, set max_depth to one. The default depth is zero, which means that only the attributes of the object itself are searched.

By default, the search will not follow references into other design objects. Setting the visit_externals flag to true will expand the search to objects not in the initial design object.

See Also

Searching for Objects by Type; RoseDesign::findObjects()

find_manager()

RoseManager * find_manager(
	RoseManagerType typ
	); 

An object can have a list of manager objects. Each new class of manager must have a unique RoseManagerType identifier. This identifier is used to distinguish each manager from the others in the list. The find_manager() function accepts a manager type and searches the list for a manager of that type. If a manager of that type is not present, the function returns NULL.

Given a SimpleManager class, we would check to see if an object had a SimpleManager in the following manner:

RoseObject * rose_obj;
SimpleManager * mgr;

mgr = (SimpleManager *) rose_obj-> 
       find_manager (SimpleManager::class_type());

See Also

Manager Objects; RoseManager; RoseObject::add_manager(); RoseObject::remove_manager();

getAttribute()

RoseAttribute * getAttribute(
	const char * att_name = NULL
	);

The getAttribute() functions search the EXPRESS definition of an object for a RoseAttribute object that describes a particular attribute. The function searches using the name of an attribute. The function is called without any parameters for RoseAggregates and RoseUnions, since they contain only one attribute.

RoseDesign * d;
Point * pt = pnewIn(d) Point;

ListOfPoint * points = pnewIn(d) ListOfPoint;
RoseAttribute * att;

// Get the attribute definition for the "x" field 
x_att = pt->getAttribute (x);

// Print the name and the type of the attribute 
printf (Name is %s\n,att->name());
printf (Type is %s\n,att->slotRoseType()->name());

// Now use the function to find the type of an aggregate.
// Since aggregates only have one attribute, we don't need
// an attribute name.
att = points-> getAttribute();

// Print the type of the attribute which would be Point.
// The name of the attribute is not important. 
printf (Type is %s\n,att->slotRoseType()->name());

See Also

Searching for Attributes; RoseDomain::findTypeAttribute()

get<type>()

<type_ref> get<type>(
	RoseAttribute * att
	);

<type_ref> get<type>(
	const char * att_name
	);

<type_ref> get<type>(           /* for aggregates and selects*/
	unsigned index = 0
	);

The RoseObject class defines a series of late-bound functions for accessing the attributes of any object. These functions can be used on entity instances, selects and aggregates. There are three versions of the functions. The first accepts the name of an attribute, the second accepts the RoseAttribute object describing an attribute and the third accepts an index within an aggregate. The table below shows the name and return type for each function:

<type> <type_ref>
Binary char *
Boolean RoseBoolean
Double double
Float float
Integer int
Logical RoseLogical
Object RoseObject *
String char *

The names of functions are getObject, getInteger, getDouble, and so on.

The get<type>() functions that operate on aggregates return the value at the given index in the aggregate. Aggregates indexes begin at zero.

RoseObject * obj, * cat;
RoseLogical u_closed, v_closed;
char * desc;

cat = obj->getObject(category);
desc = obj->getString(description);
u_closed = obj->getLogical(u_closed);
v_closed = obj->getLogical(v_closed);

The following example assumes that strings is an aggregate of strings:

RoseObject * strings;

if (!strings-> size())
     printf (No strings\n);
else {
     printf (First %s\n, strings->getString(0);
     printf (Last %s\n,  strings->getString(strings-> size()-1);
}

See Also

Late-bound Functions; RoseObject::put<type>()

isa()

RoseBoolean isa(
	RoseTypePtr& class_type
	);

RoseBoolean isa(
	RoseDomain * domain
	);

RoseBoolean isa(
	const char * domain_name
	);

The isa() functions examine the type of an object. The RoseType version examines the C++ class, while the RoseDomain version and name version examine the EXPRESS definitions. The functions return true if the object is of the same C++ class or EXPRESS definition, or a more specific definition.

The following example tests an object to see if it is an instance of a particular C++ type and EXPRESS type:

RoseObject * obj;
if (obj-> isa (ROSE_TYPE(Point)) {
    printf (Object is an instance of the C++ Point class\n);

if (obj-> isa (ROSE_DOMAIN(Point)) {
    printf (Object is an instance of the EXPRESS Point entity\n);

if (obj-> isa (Point)) {
    printf (Object is an instance of the EXPRESS Point entity\n);

See Also

EXPRESS Data Dictionary; C++ Type Information; RoseDomain::typeIsa(); RoseObject::classType(); RoseObject::domain()

isExternal()

RoseBoolean isExternal(
	RoseAttribute *att
	);

RoseBoolean isExternal(         /* for aggregates and selects*/
	unsigned index = 0
	);

The isExternal() functions test whether the value of an attribute is reference to an object in the same design or an external design. The version which takes an index is for aggregates of objects.

When reading objects from secondary storage, attributes that contain external references are usually not resolved immediately. When called on an attribute that contains an unresolved external reference, the getObject() function as well as the access functions generated by the EXPRESS compiler automatically resolve references. The isExternal() functions do not automatically resolve these references.

The following example shows how to test if an attribute contains a reference to an external design:

RoseObject * obj;
if (obj-> isExternal (obj-> getAttribute (contents)))
    printf (Attribute refers to an external design\n);

See Also

Object Identifiers and References Between Designs; RoseObject::isUnresolved(); RoseObject::resolveExternals()

isPersistent()

RoseBoolean isPersistent();

Returns true if the RoseObject is persistent, false otherwise. An object is persistent if it belongs to a design. Persistent objects are created using pnew/pnewIn.

RoseObject * obj;
if (obj-> isPersistent())
      printf (Object is persistent\n);
else  printf (Object is non-persistent\n);

See Also

EXPRESS-defined C++ Objects; RoseDesign::pnewInstance(); RoseObject::design()

isUnresolved()

RoseBoolean isUnresolved(
	RoseAttribute *att
	);

RoseBoolean isUnresolved(       /* for aggregates and selects*/
	unsigned index = 0
	);

The isUnresolved() functions test whether the value of an attribute is an unresolved external reference. Like the isExternal() function, isUnresolved() does not automatically resolve references. The version which takes an index is for aggregates of objects.

The following example shows how to test if an attribute contains an unresolved reference to an external design:

RoseObject * obj;
if (obj-> isExternal (obj-> getAttribute (contents))) {
    printf (Attribute refers to an external design\n);
    if (obj-> isUnresolved (obj-> getAttribute (contents)))
	  printf (Attribute is unresolved\n);
    else  printf (Attribute is resolved\n);
}

See Also

Object Identifiers and References Between Designs; RoseObject::isUnresolved(); RoseObject::resolveExternals()

isUnset()

RoseBoolean isUnset(
	RoseAttribute * att, 
	unsigned index=0
	);

RoseBoolean isUnset(
	const char * att_name, 
	unsigned index=0
	);

The isUnset() function tests if an attribute contains the appropriate NULL value for the attribute type. Null attributes are written as a $ in a Part 21 file. The unset() function will assign the appropriate NULL to an attribute.

if (obj->isUnset(of_product) { 
    printf (No product specified);
}

managers()

RoseManager * managers();

The managers() function returns the head of a linked-list of managers. Managers are auxiliary objects that store extra information about a RoseObject. Programs can define subclasses of the RoseManager class in order to store extra information with data objects. The ROSE library may also add various managers to an object to hold overflow attributes, external references, and other such data.

When a RoseObject is destroyed, all of the managers registered to the object are also destroyed. Both persistent and non-persistent objects can have managers.

The following example traverses over the managers registered to an object. Applications can find specific types of managers using the RoseObject::find_manager() function:

RoseObject * obj;
RoseManager * mgr = obj-> managers()
unsigned i = 0;

while (mgr) {
    i++;  mgr = mgr-> next();
}
printf (Object has %d managers\n, i);

Special Note for Older Applications

In previous versions of the library, all persistent objects had a manager. This default manager held persistence information that is now stored elsewhere. Older programs that check for a manager to determine persistence should now the RoseObject::isPersistent() function

    BAD:  if (obj-> manager())  
    USE:  if (obj-> isPersistent())

Because of this rather large change in semantics, the old RoseObject::manager() function has been renamed RoseObject::managers(). This better represents the semantics, since the special manager returned by the old version no longer exists. It also breaks any code that relied on the outdated behavior.

See Also

Manager Objects; RoseManager

move()

void move(
	RoseDesign * new_design,
	unsigned max_depth = 0,
	RoseBoolean move_externals = ROSE_FALSE
	);

The move() function moves an object between designs. The preferred way to move one object is using the rose_move_to_design() and rose_move_to_section() functions, but the RoseObject::move() function is capable of moving a deep move of connected objects. The obejcts are moved to the default section of the new design.

The function will follow attribute references to other objects and move them as well. You can specify how many levels of references the function should follow using the max_depth parameter. For example, to move one object, use a max depth of zero. To move the object and all objects referred to by its attributes, specify a max depth of one. To move the max_depth=1 objects and any objects referred to by them, specify a max depth of two.

The copy_externals flag determines whether the function will ignore references to objects in other designs.

Point * pt;
RoseObject * design_1;
RoseObject * design_2;

pt = pnewIn (design_1) Point;    /* create in design 1 */
pt-> move (design_2);            /* move to design 2 */

pt = new Point;            /* create non persistent object */
pt-> move (design_2);      /* make persistent by moving into a design */

See Also

Moving and Copying Objects; rose_move_to_design(); rose_move_to_section()

mutate()

The mutate() function is no longer a member of RoseObject. See rose_mutate() for more information about this operation.

oid()

RoseOID oid();

void oid(  /* internal use only */
	RoseOID new_oid
	);

The oid() function returns the unique ROSE identifier for an object. Objects are given OIDs when read from or written to ROSE working form files. New objects, and objects that have been read from a Part 21 file, have no OIDs. In these cases the oid() function returns NULL_OID.

Object identifiers are only preserved when designs are written as ROSE working form files. These identifiers allow the ROSE system to locate object across inter-file references. ROSE Universal Object Identifiers describes the use of OIDs in greater detail.

The object identifier can be explicitly set, but this is dangerous and should not be done without an understanding of the object index internals.

See Also

Object Identifiers and References Between Designs; RoseDesign::findObject()

put<type>()

RoseBoolean put<type>(
	<type_ref> val,
	RoseAttribute * att
	);

RoseBoolean put<type>(
	<type_ref> val,
	const char * att_name
	);

RoseBoolean put<type>(         /* for aggregates and selects*/
	<type_ref> val,
	unsigned index = 0
	);

The RoseObject class defines a series of late-bound functions for updating the attributes of any object. These functions can be used on entity instances, selects and aggregates. There are three versions of the functions. The first accepts the name of an attribute, the second accepts the RoseAttribute object describing an attribute and the third accepts an index within an aggregate. The table below shows the name and parameter types for each function:

<type> <type_ref>
Binary const char *
Boolean RoseBoolean
Double double
Integer int
Logical RoseLogical
Object RoseObject *
String const char *

The names of functions are putObject, putInteger, putDouble, and so on. The update functions return a non-zero value if the update succeeded. If the update did not succeed the object will be unchanged.

The put<type>() functions that operate on aggregates replace the value at the given index in the aggregate. If the index is beyond the end of the aggregate, the aggregate will be expanded by one element. The aggregate is expanded by one element regardless of whether the index is five places beyond the end or five thousand. Aggregates are indexed beginning at zero.

RoseObject * obj, * cat;
RoseLogical u_closed, v_closed;
char * desc;

obj-> putObject (cat, category);
obj-> putString (desc, description);
obj-> putLogical (u_closed, u_closed);
obj-> putLogical (v_closed, v_closed);

The following example creates an aggregate of strings and then replaces some of the values using the putString() function.

RoseDesign * design;
RoseObject * strings = design-> pnewInstance (ListOfString);

strings->putString (string zero, 0);
strings->putString (string one, 1);
strings->putString (string two, 2);

strings->putString (new string two, 2);

/* the following both just append their value */
strings->putString (string three, 3);
strings->putString (string four, 50);

The last putString() still only appends the value, despite the large index.

See Also

Late-bound Functions; RoseObject::get<type>()

recordCount()

unsigned recordCount();

The recordCount() function is used internally by the ROSE library. The function returns one in the case of entities and selects and the number of elements in the case of an aggregate. This is similar to the size() function, but provides an accurate count for the file I/O code since some objects redefine size() to provide other information. Application code should never need to use this function.

recordSize()

unsigned recordSize(); 

The recordSize() function is used internally by the ROSE library. This function number of bytes of storage per element. It returns the size of the entire C++ class in the case of entities and selects, and the size of an individual element in the case of an aggregate. Application code should never need to use this function.

remove_manager()

void remove_manager(
	RoseManagerType typ
	);

void remove_manager(
	RoseManager * mgr
	);

An object can have a list of managers. Each new class of manager must have a unique RoseManagerType identifier to distinguish it from the others in the list. The two versions remove and destroy specific manager given by pointer or the first manager with a particular type identifier. The manager must define a destructor that does all appropriate cleanup. The particulars of using managers are described in Manager Objects.

Given a SimpleManager class, we would remove a SimpleManager in the following manner:

RoseObject * rose_obj;

rose_obj-> remove_manager (SimpleManager::class_type());

See Also

Manager Objects; RoseManager; RoseObject::add_manager(); RoseObject::find_manager();

resolveExternals()

void resolveExternals(
	RoseBoolean deep_resolve = ROSE_FALSE
	);

The resolveExternals() function iterates over the attributes of a RoseObject and resolves any references to objects in different designs. If the deep_resolve parameter is true, the routine will recursively resolve references to any object that it can reach from the initial object.

References to external designs are normally resolved only when an attribute is first accessed. This function allows you to resolve all external references at one time.

The following example uses a RoseCursor to traverse an entire design object and resolves all references to external objects:

RoseDesign * design;
RoseCursor objs;
RoseObject * obj;

/* Resolve external references in all objects */
objs.traverse (design);
while (obj = objs.next())
    obj-> resolveExternals();

See Also

Object Identifiers and References Between Designs; RoseObject::isExternal(); RoseObject::isUnresolved()

size()

virtual unsigned size();

The size() function returns the number of elements in an object. It is normally used for determining the number of elements in an aggregate. The function normally returns one in the case of entities and selects but can be customized by subclasses to return different values. For example, the RoseDictionary class is an entity, but overrides the size function to return the number of name mappings it contains.

The following example shows the use of the size() function in a loop that prints the contents of a list of strings. Note that the function is only called once in the initialization. Calling the function each time in the comparison would be wasteful.

ListOfString * strings;
unsigned i, sz;

for (i=0, sz=strings-> size(); i<sz; i++)
     printf (Element %d is %s\n, i, strings-> get(i));

slotAddress()

RoseDataPtr slotAddress(
	RoseAttribute * att, 
	unsigned index
	);

The slotAddress() function is an internal ROSE library function used to find the memory address of an attribute of an entity or element of an aggregate. This function is used internally and should be avoided by application code.

slotAttribute()

RoseAttribute * slotAttribute (void * slotaddr);

The slotAttribute() function is an internal ROSE library function used to find the attribute for a memory address in an entity. It returns the current attribute for a select and the only attribute for an aggregate. This is an internal function and should be avoided by application code.

slotType()

RoseTypePtr& slotType(
	RoseAttribute * att,
	unsigned index
	);

The slotType() function is an internal ROSE library function used to find the RoseType information for an attribute of an entity or element of an aggregate. This function is used internally and should be avoided by application code.

usedin()

RoseAggregate * usedin( 
	RoseDomain * search_domain,   /* target type */ 
	RoseAttribute * search_att, 
	RoseAggregate * return_values
	);

The usedin() function implements the EXPRESS USEDIN. This returns all objects that reference the calling object in a particular attribute, much like constructing an inverse attribute on demand. This function looks at all objects of the given type in the design that owns the object being searched for. If the attribute to be searched is an aggregate or select, the function will search through the contents of each.

The search_domain parameter describes the type of object to examine. If this is null, the function will examine all entity instances (RoseStructure objects) in the design. The search_att parameter describes the attribute to examine. If null, all attributes of an object will be examined.

The function expects a RoseAggregate object to pass back the pointers to the matching objects. If this is null, a ListOfRoseObject will be created. It is the programmer's responsibility to free this object when no longer needed.

The usedin() function uses backpointers to improve performace if they are present (Backpointers). This can result in a significant performance boost if usedin() is called many times. You must take care if you are changing the design at the same time, however, because usedin() has no way to know if the backpointers are out-of-date.

Consider the following definition from an assembly schema:

ENTITY assembly;
INVERSE
    contents : SET [1:?] OF part FOR owner;
END_ENTITY;

ENTITY part;
    owner : assembly;
END_ENTITY;

The example below shows how one might use the usedin() function with the assembly schema. Given an assembly object, this code fragment find the part or parts that own the assembly.

unsigned i, sz;
ListOfpart contents; 

assembly *      aobj
RoseDomain *    search_domain;
RoseAttribute * search_att;

search_domain = ROSE_DOMAIN (part);
search_att = search_domain-> findTypeAttribute (owner);

aobj-> usedin (search_domain, search_att, &contents);
for (i=0, sz=contents.size(); i<sz; i++)
{
    /* loop over the part objects */
}

See Also

EXPRESS Usedin Function; Backpointers

unset()

void unset(
	RoseAttribute * att,
	unsigned index=0
	);

void unset(
	const char * att_name, 
	unsigned index=0
	);

The unset() function sets an attribute value to NULL. This is the equivalent of calling one of the put functions with the correct NULL value for the attribute type.

obj->unset(of_product);

unvisit()

void unvisit();

The unvisit() function is used to remove a mark when traversing objects within a design. The visit() function marks an object while the unvisit() function removes a mark. These traversal functions can only be used within a RoseInterface::beginTraversal()/endTraversal() block. Marking Objects During Traversal describes this process in greater detail. See the wasVisited()() function for an example.

visit()

void visit(); 

The visit() function is used when traversing objects within a design. The visit() function marks an object for the wasVisited() function. The unvisit() function can be used to reverse this process. These traversal functions can only be used within a RoseInterface::beginTraversal()/endTraversal() block. Marking Objects During Traversal describes this process in greater detail.

See the RoseObject::wasVisited() for an example.

wasVisited()

RoseBoolean wasVisited();

The wasVisited() function is used to test individual objects when traversing a design. The function returns true if the object has been previously marked by the visit() function. Traversal functions can only be used within a RoseInterface::beginTraversal()/endTraversal() block.

The following example uses a RoseCursor to traverse an entire design object and perform some operation on objects. Object marking is used to insure that each object is only considered once. The dosomething() function can mark other objects and the wasVisited() test will prevent the loop from operating on them again.

RoseDesign * design;
RoseCursor objs;
RoseObject * obj;

ROSE.beginTraversal();
objs.traverse (design);
while (obj = objs.next()) {
    if (!obj-> wasVisited()) {    /* test for mark */
	obj-> visit();         /* mark */
	dosomething (obj);
    }
    else {
	/* object is marked, we could use unvisit()
	 * to remove the mark.
	 */
    }
}
ROSE.endTraversal();

See Also

Traversing Objects Within a Design; RoseInterface::beginTraversal(); RoseInterface::endTraversal()