[Enterprise Extensions only]

C++ bindings for CORBA Union types

Union fields are not directly accessible to C++ programmers. Instead, the C++ mapping for IDL unions defines a class that provides accessor methods for the union discriminator and the corresponding union fields. The union discriminator accessor is named _d. The union field accessors are named using the IDL union field names and are overloaded to allow both reading and writing.

Note: A deviation from the CORBA specifications exists; there is no support of longlong discriminators in unions.

Setting a union's value using a field accessor automatically sets the discriminator, and releases the storage associated with the previous value, if any. It is an error for an application to attempt to access the union's value through an accessor that does not match the current discriminator value. It is also an error for the application to use the discriminator modifier method to implicitly switch between difference union members.

Unions with implicit default members (those that do not have an explicit default case and do not list all possible values of the discriminator as cases) provide a _default method, for setting the discriminator to a legal default value. This method causes the union's value to be composed only of the legal default value, because there is no explicit default member in this case.

A _var type is defined, for managing a pointer to a union in dynamically allocated memory.

To illustrate the C++ bindings for IDL unions, consider the following IDL:

module A 
{
   interface X 
   { 
   };
   union U switch (long) 
   {
      case 1: long u1;
      case 2: string u2;
      case 3: X u3; 
   };
};

The following code illustrates usage of the C++ bindings corresponding to the previous IDL:

{
   X_ptr x = // get an X somehow 
   A::U_var uv = new A::U;
   uv.u2((const char*) "testing");  // sets the discriminator to 2 
   // and copies the string
   if (u._d() == 2)// the condition evaluates to true
   u.u1(23); // frees the string, and sets the discriminator to 1
   if (u._d() == 1) // the condition evaluates to true
   u.u3(x);  // duplicates x and sets discriminator to 3
}

The default constructor of a union class does not initialize the discriminator or the union members, so the application must initialize the union before accessing it. The copy constructor and assignment operator perform deep copies. The assignment operator and destructor release all storage owned by the union.

With respect to memory management, accessor and modifier methods for union members work similarly to those for struct members. Modifier methods make a deep copy of their input when passed by value (for simple types) or by reference (for constructed types). Accessor methods that return a non-const reference can be used by the application to update a union member's value, but only for struct, union, sequence, and any members.

The modifier method for a string union member makes a copy when given a const char* or a String_var, but not when given a char*. As shown in the example above, a string literal should not be assigned to a union without an explicit "const char*" cast. The accessor method for a string union member returns a const char*, therefore the string union member cannot be modified. (This is done to prevent the string union member from being assigned to a String_var, resulting in memory management errors.)

The modifier method for an object reference union member always duplicates the input object reference and releases the previous object reference value, if any. The accessor method for an object reference union member does not duplicate the returned object reference, because the union retains ownership of it.

The accessor method for an array union member returns a pointer to the array slice. The application can thus read or write the union-member array elements using subscript operators. If the union member is an anonymous array (one without an explicit type name), the union defines (typedefs) the slice type, by cocatenating a leading underscore and appending "_slice" to the union member name.