Overview

The RoseDictionary class is the base class for parameterized dictionary classes. Dictionaries are used to associate names with values. These are normally used by the ROSE library to provide indicies, but can also be used by appliations. Unfortunately, EXPRESS has no notion of a dictionary structure, so new dictionary classes can not be defined using EXPRESS. As such, they are useful within ROSE programs, but can not appear within STEP data sets.

The RoseDictionary class is derived from RoseStructure and contains two aggregates. The first is a list of string keys. The second is a list of values. The first element in the key list corresponds to the first element in the value list, and so on. The dictionary class contains a hash table for fast key lookups.

Dictionary Structure

Dictionary Structure

Defining RoseDictionaries

Dictionaries are parameterized classes. Like aggregates, the classes name is constructed by concatenating the underlying type:

    DictionaryOfRoseObject     /* compound notation */
    Dictionary(RoseObject)     /* DEPRECATED */

The ROSE library defines dictionaries for RoseObject and primitives values. If it becomes necessary to define dictionaries classes for specific STEP data classes, it can be done using declare and implement macros as shown below.

Before defining a dictionary, be sure that a list of the appropriate element type has already been declared.

    ROSE_DECLARE_AGG(Dictionary,element_type);
    ROSE_IMPLEMENT_AGG(Dictionary,element_type);
    
    ROSE_DECLARE_AGG(Dictionary,Point)       /* declare a point dictionary */
    ROSE_IMPLEMENT_AGG(Dictionary,Point);

The parameterized class can be given additional functions using a variant of the declare() macro:

    ROSE_DECLARE_AGG_BEGIN (Dictionary,Point);
    ...
    {additional functions}
    ...
    ROSE_DECLARE_AGG_END;

Refer to Parameterized Aggregate Classes for more about dealing with parameterized classes.

Dictionaries of Non-EXPRESS Objects

A non-persistent dictionary can be defined for objects that are not described by EXPRESS. These dictionaries might be useful for indexing non-persistent application data. For example, to create a dictionary of some Widget GUI class:

Since the Widget class was not created by the EXPRESS compiler, we must create some C++ type information for the class. Next, declare a non-persistent parameterized list and dictionary for the Widget class:

    extern RoseTypePtr ROSE_TYPE(Widget);
    declare(npList,Widget);
    declare(Dictionary,Widget);    /* does not need the np prefix */

We would then provide a basic implementation of the Widget C++ type information and the implementations for the parameterized classes:

    RoseTypePtr ROSE_TYPE(Widget) ("Widget", sizeof(Widget));
    implement(npList,Widget);
    implement(Dictionary,Widget);  /* does not need the np prefix */

RoseDictionary Member Functions

The following sections describe the functions available on each dictionary class. Some of these functions are defined by RoseDictionary and some are defined by the parameterized classes. The documentation for the parameterized functions use the placeholder <class_name> to indicate the C++ class name and the the placeholder <type_ref> to indicate C++ element type. For example:

    <class_name>             <type_ref>
    DictionaryOfPoint        Point *        /* stores pointer to the object */
    DictionaryOfRoseObject   RoseObject *   /* stores pointer to the object */
    DictionaryOfInteger      int            /* stores copy of the integer */
    DictionaryOfDouble       double         /* stores copy of the double */
    DictionaryOfString       char *         /* stores copy of the string */

Predefined Dictionary Classes

The ROSE library defines the following dictionary classes:

    DictionaryOfBoolean
    DictionaryOfFloat
    DictionaryOfInteger
    DictionaryOfString
    DictionaryOfRoseObject
    DictionaryOfRoseAttribute
    DictionaryOfRoseDesign
    DictionaryOfRoseDomain

add() / put()

<class_name> * add(
	const char * key,
	<type_ref> val
	);

<class_name> * put(
	const char * key,
	<type_ref> val
	);

The add() and put() functions are the same. These functions associate a key with a value. If a key is already in the dictionary, the function replaces the old value. If the key was not already in the dictionary, the function creates a new key/value pair in the dictionary.

Example

The following example creates a dictionary and fills it with some objects.

    Dictionary(Point) * d = new Dictionary(Point);
    
    d_ptr-> put ("topleft", new Point);
    d_ptr-> put ("topright", new Point);
    d_ptr-> add ("bottomleft", new Point);
    d_ptr-> add ("bottomright", new Point);

caseSensitive()

RoseBoolean caseSensitive();

void caseSensitive(
	RoseBoolean flg
	);

The caseSensitive() flag determines whether the keys are case sensitive. If this flag is true then "key", "KEY", and "kEy" are considered different. If this flag is false, all of these are equal. The default is case sensitive.

Consider a dictionary which is populated in a case-sensitive way and contains several keys differing only by case. Setting caseSensitive() to false will cause all but one of the variations to become unreachable. You can restore the original behavior of the dictionary by setting the flag to true.

find() / operator []

<type_ref> find(
	const char * key
	);

<type_ref> operator[](
	const char * key
	);

The find() function searches the dictionary for an item with the specified key by performing a hashed search on the list of names. If a key/value pair is found, the function will return the value. If the search is unsuccessful the function returns null. The index operator is an alias for the find() function and is useful for dictionaries on the stack.

Example

The following example creates two dictionaries and fills them with some objects, then uses the find() function and index operator to find them again.

    Point * p;
    Dictionary(Point) d_stack;
    Dictionary(Point) * d_ptr = new Dictionary(Point);
    
    d_stack.put ("topleft", new Point);
    d_ptr-> put ("topleft", new Point);
    
    p = d_stack["topleft"];
    p = d_ptr-> find ("topleft");

key()

char * key(
	<type_ref> val
	); 

The key() function searches the dictionary for a key/value pair with the specified value, and if the value is present, returns the corresponding key. If the value is not present, the function returns null. If the value is present under several different keys, the function returns the first key it encounters.

listOfKeys()

ListOfString * listOfKeys();

The listOfKeys() function returns the list of string names for the values in the dictionary. This list is used by the dictionary, and should be treated as read-only data.

listOfValues()

ListOf<type_ref> * listOfValues();

The listOfValues() function returns the list of values in the dictionary. This list is used by the dictionary, and should be treated as read-only data.

removeKey()

void removeKey(
	const char * key
	);

The removeKey() function searches a dictionary for a key/value pair with the specified key. If such an entry exists, it is removed from the dictionary. Objects removed from the dictionary are not destroyed by this function.

removeValue()

void removeValue(
	<type_ref> val
	);

The removeValue() function searches a dictionary for all key/value pairs with the specified value. If a value has several different keys, all are removed from the dictionary. Objects removed from the dictionary are not destroyed by this function.

size()

unsigned size();

The size() function returns the number of key/value pairs elements in the dictionary.