Next Previous Up Top


4 europa Level 0: The Proxy Model

4.2 Object and Class Representation

4.2.1 - The EC_Any Class
4.2.2 - Class representation: EC_Class
4.2.3 - Member Function Representation: EC_Mb_Fct
4.2.4 - Mapping and conversion primitives
4.2.5 - Generation of information

4.2 Object and Class Representation


An important feature is the capability to automatically achieve (un)marshalling of objects between processes and address spaces.

4.2.1 The EC_Any Class

This first class allows for handling of C++ values (fundamental, objects, etc.) in a generic manner. The types associated with an object is always the dynamic type.

For a class A, the object can be of type A&, A, A*, A**, etc. (implementation dependent). When the object is reified, it means that there is a proxy associated with the object itself, denoted by the function is_reified. The type then is, for instance, ReifiedA* which is compatible with an A*, and all ancestors of A; it can be seen as a derived class of A.

namespace EC
{
	class EC_Any
	{
	 public:
		EC_Any ();
		EC_Any (const EC_Any&);
		~EC_Any ();
		EC_Any &operator= (const EC_Any&);

		EC_Class cid(); // get class id

		// Any creation
		EC_Any (*** all basic types ***);
		EC_Any (EC_Class c, void *value);
		// value must be consistent with c

		// Extraction
		bool operator>>= tconst EC_Any& , *** all basic types ***);
		bool operator>>=(const EC_Any&, *** all EC_Class types ***);
		bool is_null (); // Check if a pointer is null
		// Advanced functions for dynamic control of reification
		EC_Proxy* is_reified(); // Returns the proxy if the current
		// object is reified. Null otherwise.
		void reset_reified(EC_Proxy* p);
		// Change the value (proxy, and everything below)
		// of a reified object. Keep the same type.

		// Modification of pointer or reference types of current object,
		// returns false if operation is illegal
		bool deref (); // dereference a pointer object
		bool derefs (); //       upto the object without pointer
		bool addptr (); // add a pointer to the object
	} ;
}

The EC_Any class is used as follows:

int i=14;
A* a = new A ();
EC_Any anyl(i), any2(a);
int j;
A* a2;
if ( anyl >>= j )
{
	// use the value j
}
if ( any2 >>= a2 )
{
	// use the value b
}

4.2.2 Class representation: EC_Class

All C++ types (fundamentals and compounds) are uniformly represented through the EC_Class (int, float, etc., array, struct, and, of course, class). This class is both a meta-class for the representation and manipulation of C++ objects, and (by construction) a type code that can be used as an id for types.

Function members such as mb_nb, mb_name, mb_get, etc. provide information on the class structure, and access to the member data. Thanks to these features, generic and optimized algorithms for (un)marshalling of objects can be defined.

For fundamental types, mb_nb is equal to 1, and functions mb_nb, mb_name, mb_get, etc. are valid. The enum EC_Type below provides for switch discrimination of fundamental types. For C++ arrays, in the case of a static array, mb_nb gives the number of element, and mb_get provides access to them. For unknown size arrays, mb_nb returns 0.

Finally, a set of functions allows the manipulation of pointer or reference types.

addref, applied on a type A returns the EC_Class for &~A;

ptr applied on A again returns *A, while applied on ~A it returns A;

deref returns A when applied on *A; while

derefs remove all the pointer access upto a non-pointer type (returns A on *...*A).

All these functions return 0 if operation is illegal, or reaches the implementation limits (e.g. no more than ***A is represented).

namespace EC
{
	class EC_Class
	{
	 public:
		char* name (); // Class name
		// class structure (data members)
		// for (un)marshalling of objects, etc.
		int mb_nb ();                   // number of data members
		char* mb_name (int rank); // names
		EC_Class mb_type (int rank); // type
		EC_Any mb_get (int rank, EC_Any obj);             // get a member
		void mb_set (int rank,EC_Any obj,EC_Any value); // set a member
		size_t object_size ();        // size of instance object

		// class member functions
		int mbf_nb ();                  // number of member functions
		EC_Mb_Fct mbf_get (int rank); // get a member function representation

		// Object instantiation
		EC_Any new_obj (EC_Call* c);
		// Create a new object of the current class, calls the
		// constructor specified by EC_Call,
		// default constructor if c is null
		EC_Any new_obj ();
		// Same without constructor being called, allocation only
		EC_Any new_reified_obj (EC_Proxy* pr);
		// Create, for the current class, a reified object with the
		// proxy object pr. Returns null if class cannot be reified
		// The actual object itself is not created since it is
		// the proxy responsibility.
		bool is_reifiable ();
		// Is a class that can be reified?

		// Classification of types:
		// Inheritance
		bool is_derived_from (EC_Class c); // Is a kind of?
		// RTTI information
		bool is_polymorphic(); // Is a polymorphic type?

		// Qualifiers
		bool is_const();         // Is a const object?
		bool is_volatile();       // Is a volatile object?
		bool is_const_volatile(); // Is a const volatile object?

		// Is a fundamental types?
		EC_Type is_ftype (); // If not returns O,
		// otherwise code for use with enum EC_Type

		// Compound types
		bool is_array ();      // Is a C++ array?
		bool is_fct_ptr (); // Is a function pointer?
		bool is_mb_fct_ptr (); // Is a member function pointer?
		bool is_charst ();  // Is a char*?
		bool is_struct ();  // Is a struct?
		bool is_union ();   // Is an union?
		bool is_obj (); // Is a class (not a ref, not a pointer)?
		bool is_ref (); // Is a reference?
		bool is_ptr (); // Is a pointer?

		// Special cases for EUROPA EC_Any
		bool is_ecany ();   // An EC_Any object represented by an EC_Any?
		// Manipulation of pointer or reference types,
		// returns a non vallid EC_Class if operation is illegal
		EC_Class deref (); // dereference a pointer type
		EC_Class derefs (); // upto a non pointer type
		EC_Class addptr (); // take the pointer type
		EC_Class addref (); // take the reference type
		bool is_illegal (); // Is current EC_Class object not a valid type?

		// Equality, inequality
		bool operator == (EC_Class c);
		bool operator != (EC_Class c);

	 protected:
		// Implementation defined
	} ;
}

The following enum gives constant Class_id values to fundamental C++ types:

namespace EC
{
	enum EC_Type
	{
		ec_char, // char
		ec_uchar, // unsigned char
		ec_schar, // signed char
		ec_enum, // enumeration
		ec_short, // short integer
		ec_int, // integer
		ec_lgint, // long integer
		ec_ushort, // unsigned short int
		ec_uint, // unsigned int
		ec_ulong, // unsigned long int
		ec_wchar_t, // extended character
		ec_bool, // boolean
		ec_float, // float
		ec_double, // double
		ec_lgdouble,// long double
		ec_void, // void type
	} ;
}

4.2.3 Member Function Representation: EC_Mb_Fct

The EC_Mb_Fct class provides identification for member functions, as well as the ability to call a member on an object, with effective parameters.

namespace EC
{
	class EC_Mb_Fct
	{
	 public:
		char* name(); // Member function name

		EC_Class return_type (); // Return type
		int formal_nb();         // Number of formals parameters
		EC_Class* formals(); // List of formal parameter types
		EC_Any execute (EC_Any obj, EC_Any* eff);
		// Execute the member, using the effective parameters, and
		// returns the result. Overriding resolution (Dynamic Binding),
		// but no overloading resolution here.
		EC_Class decl_class (); // Declaration class of the member

		EC_Call* new_call(EC_Any* eff);
		// Returns a call object for the current member function
		// with effective parameters.

		bool is_static (); // Is the mb. fct. static?
	} ;
}

The member function is a constructor when its name is equal to its class name (name()==decl_class().name()), and similarly for destructor with the extra character ~. EC_Class and EC_Mb_Fct classes are meta-classes that represent information on C++ classes. They conform to the design principle of the standard class type_info which provides some basic information, and are designed with the intention of being extended according to specific needs. By specification, EC_Class and EC_Mb_Fct values must have a system wide validity (they can be passed as parameters between processes).

4.2.4 Mapping and conversion primitives

Primitives to obtain class and member identifications (EC_Class, EC_Mb_Fct), and conversion to RTTI type_info references are provided. type_info is the standard rtti class of C++.

namespace EC
{
	// Class identification: ec_cid
	EC_Class ec_cid (typename); // ec_cid(A)

	// Member identification: ec_mid
	EC_Mb_Fct ec_midl (membername);    // mid(put)
	EC_Mb_Fct ec_mid2 (typename, membername); // ec_mid(A,put)
	EC_Mb_Fct ec_mid3 (typename, membername, typename);
	// ec_mid(A,put,T1)
	EC_Mb_Fct ec_mid4 (typename, membername, typename, typename);
	// ec_mid(A,put,Tl,T2)

	EC_Mb_Fct ec_midl2 ( ... ); // ec_mid(A,put,Tl,T2, ..., T10)

	// Conversion from EC class id to RTTI type_info
	type_info& ec2rtti (EC_Class c);
	EC_Class rtti2ec (type_info& t);
}

4.2.5 Generation of information

The EUROPA standard specifies that each class or type with its name appearing within a typeid primitive, or being derived from EC_Reflect must be a reifiable class, and also have the corresponding EC_Class and EC_Mb_Fct classes to be generated and made available at runtime.

Besides this implicit generation, the europa standard provides a means to control the amount of information to be generated. An important feature is the ability to define the strategy of generation on classes that do not exist yet. The intent is to give the programmer of a library for parallel programming (Level 1) the ability to control the amount of information generated for classes that she does not know about: the application programmer classes. Level 0 provides the access to such a crucial mechanism.

The information to be generated by an europa compliant pre-processor can be classified into three categories for a given class A:

1. The ability to reify A (called reifiable).
2. The ability to access dynamically the member functions of A (member functions); corresponds to the generation of a set of EC_Mb_Fct instances.
3. The ability to access dynamically the class representation of A (class structure); corresponds to the generation of a single EC_Class class instance.

For consistency, those three degrees are classified in the following manner:

reifiable fi member functions fi class information

meaning that if A is reifiable, then it also has the generation of its member functions, and in that case it also implies that its class structure exists at runtime. Although theoretically those three degrees could be controlled independently, the current definition of the standard, for the sake of simplicity, collapses member functions and class structure controls into a single one.

As a consequence, Level 1 programmers can control the amount of information generated through two classes: EC_Reifiable and EC_Generation. All the calls to their static functions have to occur within classes that are derived from EC_Reflect.

namespace EC
{
	class EC_Reifiable
	{ // Controls classes that are reifiable at runtime
	 public:
		static void single (type_info& t);
		// Generates reifiable for a given class
		// Usage: EC_Reifiable::single (typeid(A));
		static void base (type_info& t); // All base classes
		static void derived (type_info& t); // All derived classes
		static void hierarchy (type_info& t);// Base and derived

		static void data_members (type_info& t);
		// Data member types of a given class
		static void all_data_members (type_info& t);
		// Recursively all the data members of a given class
		// (transitive closure)

		static void parameters (type_info& t);
		// Parameter types of member functions within hierarchy
		static void return_types (type_info& t);
		// Return types of member functions within hierarchy

		static void related (type_info& t);
		// Classes related to a given class: based, derived,
		// data members, parameters, and return types of
		// member functions
		static void all_related (type_info& t);
		// All classes related: transitive closures

		static void all_related_lim (type_info& t,type_info& liml,...);
		// Idem to all_related, but do not follow on the transitive
		// closures after limit types given in ellipsis parameters
		static void all_data_members_lim(type_info& t,type_info& liml,...);
		// Idem to all_data_members with limits

		static void all ();
		// For all classes in the system
}
         
namespace EC
{
	class EC_Generation
	{
		// Controls the generation of EC_Mb_Fct and EC_Class classes
	 public:
		static void single (type_info& t);
		// Generates EC_Mb_Fct and EC_Class for a given class
		// Usage: EC_Generation::single (typeid(A));

		static void base (type_info& t); // All base classes
		static void derived (type_info& t); // All derived classes
		static void hierarchy (type_info& t);// Base and derived

		static void data_members (type_info& t);
		// Data member types of a given class
		static void all_data_members (type_info& t);
		// Recursively all the data members of a given class
		// (transitive closure)

		static void parameters (type_info& t);
		// Parameters types of member functions within hierarchy
		static void return_types (type_info& t);
		// Return types of member functions within hierarchy

		static void related (type_info& t);
		// Classes related to a given class: based, derived,
		// data member, parameters, and return types of
		// member functions
		static void all_related (type_info& t);
		// All classes related: transitive closures

		static void all_related_lim (type_info& t,type_info& liml,...);
		// Idem to all_related, but do not follow on the transitive
		// closures after limit types given in ellipsis parameters
		static void all_data_members_lim(type_info& t,type_info& liml,...);
		// Idem to all_data_members with limits

		static void all ();
		// For all classes in the system
	} ;
}

Copyright 1997 EUROPA WG

Last updated: 26 Nov 1997