This section discusses the IDL to C++ language mapping provided by the VisiBroker for C++ idl2cpp compiler, which strictly complies with the CORBA C++ language mapping specification.
 
      
      
      
      
      The IDL boolean type is defined by the CORBA specification to have only one of two values: 
1 or 
0. Using other values for a 
boolean will result in undefined behavior.
 
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      Whenever it maps an IDL string to a
char *, the IDL compiler also generates a 
String_var class that contains a pointer to the memory allocated to hold the string. When a 
String_var object is destroyed or goes out of scope, the memory allocated to the string is automatically freed.
 
      
      
         class String_var {
         protected:
               char   *
_p;
               ...
         public:               
String_var();               
String_var(char *p);               
~String_var();
               String_var&       
operator=(const char *p);
               String_var&       
operator=(char *p);
               String_var&       
operator=(const String_var& s);
               operator const 
char *() const;
               operator 
char *();
               char 
&operator[](CORBA::ULong index);
               char 
operator[](CORBA::ULong index) const;
               friend ostream&      
operator<<(ostream&, const String_var&);
               inline friend Boolean  
operator==(const String_var& s1,
                              const String_var& s2);
               ...
   };
   ...
};
 
      
      
      
      
      
      
      
      
      
      
      
         const string       str_example = this is an example;
   const 
long         long_example = 100;
   const 
boolean      bool_example = TRUE;
};
 
      
      class example :: public virtual CORBA::Object
 
      {
   ...
   static const char *str_example; /* this is an example */
   static const 
CORBA::Long         long_example; /* 100 */
   static const 
CORBA::Boolean      bool_example; /* 1 */
   ...
};
 
      
      const char *example::str_example = this is an example;
 
      const CORBA::Long             example::long_example = 100;
const 
CORBA::Boolean          example::bool_example = 1;
 
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      typedef octet                example_octet;
typedef enum 
enum_values {
   first,
   second,
   third
} 
enum_example;
 
      
      
      typedef octet                example_octet;
enum 
enum_values {
   first,
   second,
   third
};
typedef 
enum_values enum_example;
 
      
      
      
      
      
      
      class A1;
typedef A1 *A1_ptr;
typedef A1_ptr A1Ref;
class A1_var;
typedef 
A1 A2;
typedef A1_ptr A2_ptr;
typedef A1Ref A2Ref;
typedef A1_var A2_var;
 
      
      
      typedef sequence<long> S1;
typedef 
S1 S2;
 
      
      
      class S1;
typedef S1 *S1_ptr;
typedef S1_ptr S1Ref;
class S1_var;
typedef S1 S2;
typedef S1_ptr S2_ptr;
typedef S1Ref S2Ref;
typedef S1_var S2_var;
 
      
      The OMG IDL to C++ language mapping specifies that each IDL module be mapped to a C++ 
namespace with the same name. However, few compilers currently support the use of 
namespaces. Therefore, VisiBroker currently supports module to class mapping only. The code samples below show how VisiBroker Edition's IDL compiler maps a 
module definition to a 
class.
 
      
      
      
      
      
      
      
      
      
      
        
          
            | 
                •     
               | string type, bounded or unbounded | 
        
       
      
      
      
        
          
            | 
                •     
               | Other structures or unions  that contain a variable-length member | 
        
       
      
        
          
            | 
                •     
               | array with variable-length elements | 
        
       
      
        
          
            | 
                •     
               | typedef with variable-length elements. | 
        
       
      
        
        
          |  |  | 
        
          |  |  | 
        
          |  |  | 
        
          |  |  | 
        
          |  |  | 
        
          |  | array, array_slice , array_forany , and array_var | 
      
      
      
      For each fixed-length IDL structure mapped to C++, VisiBroker Edition's IDL compiler generates a structure as well as a _var class for the structure. The code samples below show how this is done. For more information on the 
_var class, see “<class_name>_var” in the 
VisiBroker for C++ API Reference.
 
      
      
      struct example {
   short a;
   long b;
};
 
      
      
      struct example {
   CORBA::Short a;
   CORBA::Long b;
};
class 
example_var
{
   ...
   private:         
example *_ptr;
};
 
      
      When accessing fields of the _var class, you must always use the 
-> operator. For example, the code sample below shows that to access the fields of the 
_var class 
ex2, the 
-> operator must always be used. When 
ex2 goes out of scope, the memory allocated to it will be freed automatically.
 
      
      
      example ex1 = { 2, 5 };
// Declare a _var class and assign it to a newly created example structure.
// The _var points to an allocated struct with un-initialized fields.
example_var 
ex2 = new example;
// Initialize the fields of ex2 from ex1
ex2->a = ex1.b; 
      
      
      
      
      interface ABC {
   ...
};
struct 
vexample {
   short       a;   
ABC       c;
   string       name;
};
 
      
      
      struct vexample {
   CORBA::Short       a;   
ABC_var       c;   
CORBA::String_var       name;
   vexample&    
operator=(const vexample& s);
};
class 
vexample_var {
   ...
};
 
      Notice how the ABC object reference is mapped to an 
ABC_var class. In a similar fashion, the string 
name is mapped to a 
CORBA::String_var class. In addition, an assignment operator is generated for variable-length structures.
 
      
      The use of _var classes in variable-length structures ensures that memory allocated to the variable-length members is managed transparently.
 
      
      
      
      
      Each IDL union is mapped to a C++ class with methods for setting and retrieving the value of the data members. Every member in the IDL union is mapped to a set of functions that serve as accessors and mutators. A 
mutator function sets the value of the data member. An 
accessor function returns the data in the data member.
 
      A special, pre-defined data member, named_d, of the 
discriminant type is also generated. The value of this discriminant is not set when the union is first created, so an application must set it before using the 
union. Setting any data member using one of the methods provided automatically sets the discriminant. A special accessor function, 
_d(), provides access to the discriminant.
 
      
      
      
      struct example_struct
{
   long abc;
};
union 
example_union switch(long)
{
   case 1: long       x; // a primitive data type
   case 2: string       y; // a simple data type
   case 3: 
example_struct       z; // a complex data type
};
 
      
      
      struct example_struct
{
         CORBA::Long       abc;
};
class 
example_union
{
   private:
         CORBA::Long       
_disc;
         CORBA::Long       
_x;
         CORBA::String_var       
_y;         
example_struct       _z;
   public:         
example_union();         
~example_union();         
example_union(const example_union& obj);
         example_union&    
operator=(const example_union& obj);
         void    
x(const CORBA::Long val);
         const CORBA::Long    
x() const;
         void    
y(char *val);
         void    
y(const char *val);
         void    
y(const CORBA::String_var& val);
         const char    
*y() const;
         void 
z(const example_struct& val);
         const example_struct&    
z() const;
         example_struct&    
z();
         CORBA::Long 
_d();
         void 
_d(CORBA::Long);
         ...
};
 
      
      
      
      In addition to the example_union class shown in the following code sample, an 
example_union_var class would also be generated. See “<class_name>_var” in the VisiBroker for C++ 
API Reference for details on the 
_var classes.
 
      
      
      
      
      
        
          
            | 
                •     
               | A char * accessor method frees any storage before ownership of the passed pointer is assumed. | 
        
       
      
        
          
            | 
                •     
               | Both const char * and String_var  accessor methods free any old memory before the new parameter's storage is copied. | 
        
       
      
      
      
      
      
      
      
      
      
      class LongSeq
{
   public:         
LongSeq(CORBA::ULong max=0);         
LongSeq(CORBA::ULong max=0, CORBA::ULong length,
                           CORBA::Long *data, CORBA::Boolean release = 0);         
LongSeq(const LongSeq&);         
~LongSeq();
         LongSeq&          
    operator=(const LongSeq&);
         CORBA::ULong          
maximum() const;
         void                  
length(CORBA::ULong len);
         CORBA::ULong          
length() const;
         const CORBA::ULong& 
  operator[](CORBA::ULong index) const;
         ...
         static LongSeq        
*_duplicate(LongSeq* ptr);
         static void          
 _release(LongSeq *ptr);
         static CORBA::Long    
*allocbuf(CORBA::ULong nelems);
         static void          
 freebuf(CORBA::Long *data);
   private:
         CORBA::Long      * _contents;
         CORBA::ULong       _count;
         CORBA::ULong       _num_allocated;
         CORBA::Boolean     _release_flag;
         CORBA::Long       _ref_count;
};
 
      
      
      
      In addition to the LongSeq class shown in the code sample below, a 
LongSeq_var class is also generated. See “<class_name>_var” in the VisiBroker for C++ 
API Reference for details on the classes. In addition to the usual methods, there are two indexing methods defined for sequences.
 
      
      
      
      
      
      
      
      
      
        
          
            | 
                •     
               | Always use allocbuf and freebuf  to create and free storage used with sequences. | 
        
       
      
      
      typedef sequence<string, 3> 
String_seq;
 
      
      
      
      
      StringSeq static_seq(3, static_array);
// Create another sequence, release flag set to 
TRUE
StringSeq 
dynamic_seq(3, dynamic_array, 1); 
      static_seq[1] = 1; // old memory not freed, no copying occurschar *str = string_alloc(2);
 
      
      
      
      
      
      interface Intf
{
   ...
};
typedef 
long L[10];
typedef 
string S[10];
typedef 
Intf A[10];
 
      
      
      typedef CORBA::Long L[10];
typedef 
CORBA::String_var S[10];
typedef 
Intf_var A[10];
 
      The use of the managed type _var for strings and object references allows memory to be managed transparently when array elements are assigned.
 
      
      The array_slice type is used when passing parameters for multi-dimensional arrays. VisiBroker's IDL compiler also generates a 
_slice type for arrays that contains all but the first dimension of the array. The array 
_slice type provides a convenient way to pass and return parameters. The following code samples show two examples of the 
_slice type.
 
      
      
      typedef long L[10];
typedef 
string str[1][2][3];
 
      
      
      
      
      
        
          
            | 
                •     
               | operator[] is overloaded to provide intuitive access to array elements. | 
        
       
      
      
      
      
      
      
      class L_var
{
   public:         
L_var();         
L_var(L_slice *slice);         
L_var(const L_var& var);         
~L_var();
         L_var&    
operator=(L_slice *slice);
         L_var&    
operator=(const L_var& var);
         CORBA::Long&    
operator[](CORBA::ULong index);         
operator L_slice *();         
operator L &() const;
         ...
   private:
         L_slice   *_ptr;
};
 
      
      A special _forany class is generated to handle arrays with elements mapped to the type 
any. As with the 
_var class, the 
_forany class allows you to access the underlying array type. The 
_forany class does not release any memory upon destruction because the 
_any type maintains ownership of the memory. The 
_forany class is not implemented as a 
typedef because it must be distinguishable from other types if overloading is to function properly.
 
      
      
      
      
      
      class L_forany
{
   public:         
L_forany();         
L_forany(L_slice *slice);         
~L_forany();
         CORBA::Long&    
operator[](CORBA::ULong index);
         const CORBA::Long&    
operator[](CORBA::ULong index) const;         
operator L_slice *();         
operator L &() const;         
operator const L & () const;         
operator const L& () const;
         L_forany& 
operator=(const L_forany obj);
         ...
   private:
         L_slice   *_ptr;
};
 
      
      
      
      
      
      
      
      inline L_slice *L_alloc();                                          
// Dynamically allocates array. Returns
// NULL on failure.
inline void 
L_free(L_slice *data);     
// Releases array memory allocated with
// L_alloc.
inline void L_copy(L:slice *_to, L_slice *_from)                  
//Copies the contents of the _from array to the _to array
inline L_slice *L_dup(const L_slice *_date)
//Returns a new copy of _date array
 
      
      A Principal represents information about client applications that are making operation requests on an 
object implementation. The IDL interface of 
Principal does not define any operations. The 
Principal is implemented as a sequence of octets. The 
Principal is set by the client application and checked by the VisiBroker ORB implementation. VisiBroker Edition for C++ treats the 
Principal as an opaque type and its contents are never examined by the VisiBroker ORB.
 
      
      
      A C++ class whose name is formed by adding an “OBV_” to the fully scoped name of the 
valuetype provides default implementations for the accessors and modifiers of the abstract base class.
 
      Applications are responsible for the creation of valuetype instances. After creation, these applications deal with those instances using only pointers. Unlike object references which map to C++ _ptr types that may be implemented either as actual C++ pointers or as C++ pointer-like objects, handles to C++ valuetype instances are actual C++ pointers. This helps to distinguish them from object references.
 
      Unlike mapping for interfaces, reference counting for valuetype must be implemented by the instance of the valuetypes. The 
_var type for a valuetype automates the reference counting. The code sample below illustrates these features.
 
      
      
      
      
      The _init class provides a way to implement a factory for the valuetypes. Since valuetypes are passed by value over the wire, the receiving end of a streamed out valuetype usually implements a factory to create a valuetype instance from the stream. Both the server and the client should implement it if there is a possibility of receiving a valuetype over the stream. The _
init class, as shown in the following code sample, which must also implement 
create_for_unmarshal that returns a 
CORBA::ValueBase *. 
      
      
      
      
      
      
      
      The C++ interfaces for the DerivedExample class are as follows:
 
      
      
      
      
      
      The mapping is similar to regular derived valuetypes except that extra information is added to the Type information of the 
DerivedExample class to indicate the truncatability to the base class Example.
 
      
      
      
      
      
      
      
      
      For reference counting, the C++ mapping provides two standard classes. The first class is CORBA::DefaultValueRefCountBase, which serves as a base class for any application provided concrete valuetypes that do not derive from any IDL interfaces. For these kinds of valuetypes, the applications are also free to implement their own reference counting mechanisms. The second class is 
PortableServer::ValueRefCountBase, which must serve as a base class for any application provided a concrete valuetype class which does derive from one or more IDL interfaces.
 
      
      A valuebox is a valuetype applied to structures, unions, any, string, basic types, object references, enums, sequence, and array types. These types do not support method, inheritance, or interfaces. A valuebox is ref counted and is derived from CORBA::DefaultValueRefCountBase. The mapping is different for different underlying types. All valuebox C++ classes provide 
_boxed_in(), boxed_out(), and 
_boxed_inout() for mapping to the underlying types. The factory for a valuebox id automatically registered by the generated stub.
 
      See the OMG CORBA 2.3 idl2cpp specification, Chapter 1.17, for more information. The factory for a valuebox is automatically registered by the generated stub.
 
      
      
      
      
      
      
      
      
      
      
      There is a _var class, an 
_out class, and a class derived from 
CORBA::AbstractBase that implements the methods described in the previous code samples.