The ROSE library defines a variety of preprocessor macros and simple types. The most common ones are documented below.

NULL Values

ROSE_NULL_INT        /* null int value */
ROSE_NULL_REAL       /* null double value */
ROSE_NULL_ENUM       /* null enumeration value */
ROSE_NULL_BOOLEAN    /* null boolean/logical value */
ROSE_NULL_LOGICAL    /* null boolean/logical value */
ROSE_NULL_STRING     /* null string/binary value */

ROSE_NULL_INDEX      /* returned by find() functions */

Each primitive type has a null value as shown above. These values can be assigned to unset an attribute field. When reading or writing a Part 21 file, these values represent the $ unset symbol.

The null value for object fields is just a null pointer. The null string value is also just a simple null pointer, but the ROSE_NULL_STRING symbol is provided for completeness.

The integer and floating point nulls are in-band values that are less likely to occur in general use. Following the values established by the SDAI C++ binding (ISO 10303-23), we use INT_MIN and DBL_MIN. The ROSE Math library has additional comparison macros for testing null floating point values

The null values for boolean and logical are identical and may be used interchangeably. The enums generated from EXPRESS contain a null value equivalent to the ROSE_NULL_ENUM constant, but strongly-typed. When using data dictionary calls, the general constant is fine, but when using generated classes, you will need the strongly typed version.

The ROSE_NULL_INDEX value is returned by the aggregate search functions to indicate no value found.

Late-bound applications may find it easier to use the RoseObject::isUnset() or RoseObject::unset() functions.

SomeObject * obj;

obj-> obj_value(NULL);

obj-> str_value(NULL);
obj-> str_value(ROSE_NULL_STRING);  /* also fine */

obj-> real_value(ROSE_NULL_REAL);
obj-> int_value(ROSE_NULL_INT);

obj-> bool_value(ROSE_NULL_BOOLEAN);
obj-> logical_value(ROSE_NULL_BOOLEAN);

obj-> enum_value((SomeEnum) ROSE_NULL_ENUM);
obj-> enum_value(SomeEnum_NULL);   /* same value */

if (!obj-> obj_value()) printf (object unset\n);

/* plain and alternate */
if (!obj-> str_value()) printf (string unset\n);
if (obj-> str_value() == ROSE_NULL_STRING)   /* alternate */
    printf (string attribute is unset\n);

/* plain and alternate from rosemath.h */
if (obj-> real_value() == ROSE_NULL_REAL) printf (floating point unset\n);
if (ROSE_FLOAT_IS_NULL(obj-> real_value())) printf (floating point unset\n);

if (obj-> int_value() == ROSE_NULL_INT) printf (integer unset\n);
if (obj-> bool_value() == ROSE_NULL_BOOLEAN) printf (bool unset\n);
if (obj-> logical_value() == ROSE_NULL_BOOLEAN) printf (logical unset\n);

if (obj-> enum_value() == SomeEnum_NULL) printf (enum unset\n);
if (obj-> enum_value() == (SomeEnum) ROSE_NULL_ENUM) printf (enum unset\n);

RoseBoolean and RoseLogical

typedef char RoseBoolean;
typedef char RoseLogical;

/* Values for booleans and logicals */
#define ROSE_FALSE      (0)
#define ROSE_TRUE       (1)
#define ROSE_UNKNOWN    (2)

The RoseBoolean and RoseLogical defined types represent boolean and logical values in EXPRESS-defined data. These types can take on the ROSE_TRUE, ROSE_FALSE, or ROSE_UNKNOWN values. In addition, there are separate null values discussed above.

Local and global rules in the EXPRESS language return a logical value, and the convention is that any non-false value is considered to pass. In the values above, unknown is a non-zero value so simply testing for zero will get the EXPRESS behavior.

RoseDesignSectionType (enum)

enum RoseDesignSectionType {
	ROSE_SECTION_ANY = 0,	/* not a valid type, used by cursors */

The RoseDesignSectionType enumeration describes how objects in a RoseDesignSection map to the organization of a Part 21 file. The RoseDesignSection::section_type() function returns one of these values.

The ROSE_SECTION_DATA and ROSE_SECTION_HEADER values indicate the Part 21 header and data sections. The third edition of Part 21 added a reference section, which is indicated by ROSE_SECTION_REFERENCE. The ROSE_SECTION_SYSTEM value is used for a section that contains objects created and managed by the ROSE library. A system section is not written to a Part 21 file, but it is stored by a ROSE working form file.

The RoseCursor::section_type() function makes the cursor return objects from a particular type of design section. The ROSE_SECTION_ANY type indicates that all types of section should be traversed.

RoseNodeType (enum)

enum RoseNodeType {
	ROSE_INTEGER,     /* int */
	ROSE_FLOAT,       /* float */
	ROSE_BOOLEAN,     /* RoseBoolean (typedef char) */
	ROSE_LOGICAL,     /* RoseLogical (typedef char) */
	ROSE_STRING,      /* RoseSTR  (typedef char *) */
	ROSE_OID,         /* RoseOID  (typedef unsigned long) */
	ROSE_DOUBLE,      /* double */
	ROSE_BINARY,      /* RoseBinarySTR (typedef char *) */
	ROSE_ENUM,        /* For enumerated types */

	ROSE_LAST_PRIM,   /* Boundary between prims & objs */
	ROSE_STRUCT,      /* RoseStructure Object */
	ROSE_UNION,       /* RoseUnion Object */
	ROSE_AGGREGATE,   /* RoseAggregate Object */
	ROSE_DESIGN,      /* RoseDesign Object */
	ROSE_UNDEFINED    /* RoseObject - Unknown Type */

The RoseNodeType enumeration is used internally by the ROSE library to describe the fundamental form of a data value. It contains enums for many more basic types than are actually used. The RoseAttribute::slotNodeType(), RoseDomain::typeNodeType(), and RoseType::nodeType() functions return the value for a type definition or attribute.

This is a low-level interface used internally. The data dictionary RoseDomain or RoseType information provides more specific type descriptions.


<type> * ROSE_CAST (type,object)

The ROSE_CAST() macro is an extension to C++ pointer type casting that allows casting from sub to supertype and from super to subtype, even on classes with virtual base classes. It uses the ROSE C++ type information to provide run-time type checking as well. The macro works by concatenating tokens so it is important not put spaces around the type name.

See Pointer Type Casting for more discussion.

In the example below, the ROSE_CAST() macro is used to convert the result of a search to a Point reference.

Point * p;
RoseObject * obj;

obj = ROSE.findObject(some_point);  /* search for an object */
p = ROSE_CAST(Point,obj);             /* cast RoseObject* to Point* */


unsigned ROSE_COUNT (array)

The ROSE_COUNT() macro returns the number of elements in a static array of elements. This is useful when specifying a size to the RoseErrorContext constructor.


RoseDomain * ROSE_DOMAIN (type)

The ROSE_DOMAIN() macro returns the EXPRESS data dictionary information for a C++ class or primitive type understood by ROSE. Classes must be linked into an application for this macro to work. The macro works by concatenating tokens so it is important not put spaces around the type name.

RoseDomain * point_domain = ROSE_DOMAIN(Point);
RoseDomain * string_domain = ROSE_DOMAIN(STR);


void ROSE_LOAD (type)

The ROSE_LOAD() macro circumvents problems with some optimizing linkers. Most applications will not need to call this macro because they will just call stplib_init() or ifclib_init(), which will handle everything.

If an application does not explicitly create instances of a particular class, some linkers will not bring in the class definition from a library. This macro will force the linker to bring in the specified class. The macro works by concatenating tokens so it is important not put spaces around the type name

When using the ROSE library to read STEP or IFC data from a file, the linker might think some classes are unused, particularly if your application only references a base class and calls virtual functions to do its work. See Force-Linking Classes for additional discussion.

The following will force the C++ classes Point and Line to be linked in. It is not necessary to bring in the header files for the classes.



RoseTypePtr& ROSE_TYPE (type)

The ROSE_TYPE() function returns the C++ type information for a C++ class or primitive type understood by ROSE. The classes must be linked into an application for this macro to work. The macro works by concatenating tokens so it is important not put spaces around the type name

RoseTypePtr& thePointRoseType = ROSE_TYPE(Point);
RoseTypePtr& theFloatRoseType = ROSE_TYPE(float);