// Macro definitions for the C++/Perfect binding. //************************************************** //* Collection bindings //************************************************** // Variable declarations... #define PV_SET(type_of_set) _eSet< type_of_set > #define PV_BAG(type_of_bag) _eBag< type_of_bag > #define PV_SEQ(type_of_seq) _eSeq< type_of_seq > #define PV_MAP(type_of_map) _eMap< type_of_map > #define PV_PAIR(type_x_of_pair, type_y_of_pair) _ePair< type_x_of_pair, type_y_of_pair > #define PV_TRIPLE(type_x_of_triple, type_y_of_triple, type_z_of_triple) _eTriple< type_x_of_triple, type_y_of_triple, type_z_of_triple > // Operators... // See 'Miscellaneous bindings'. //************************************************** //* Ordering bindings //************************************************** // Operations... #define PO_RANK(first_item, second_item) _oRank((first_item), (second_item)) // Rank values... #define PC_RANKS_BELOW _eRank::below #define PC_RANKS_SAME _eRank::same #define PC_RANKS_ABOVE _eRank::above //************************************************** //* Regular-type (use-defined-type) bindings //************************************************** // Variable declarations... #define PV_REGTYPE(type_name) _eHndl< type_name > #define PV_SMPLUNION_WITHVOID(type_name) _eHndl< type_name > // Formal parameter declarations... #define PF_REGTYPE_IN(type_name) const type_name* #define PF_REGTYPE_CH(type_name) _eHndl< type_name >& #define PF_REGTYPELTD_CH(type_name) type_name* // Return type declarations of functions #define PR_REGTYPE(type_name) _eHndl< type_name > // function (const) return #define PR_REGTYPE_CH(type_name) _eHndl< type_name >& // selector (non-const) return // Operations... #define PO_BUILDREGTYPE(type_name, brktdargs) _eHndl< type_name >(new type_name brktdargs ) // Usual instance access operations on regular (handle types) - use the '.._ACCESS_..' version when calling functions or // schemas that don't change the current object; use the '.._CHANGE_..' version when calling schemas that do modify the // current object ... #define PO_ACCESS_REGTYPE(instance) (instance).operator*() #define PO_CHANGE_REGTYPE(instance) (instance).Change() // Special access operators, for use when passing pointers to C++ functions - use spareingly and carefully! ... #define PO_ACCESS_REGTYPE_NCONST(instance) (*(instance).ChangePtr()) #define PO_ACCESS_REGTYPE_NCONST_PTR(instance) ((instance).ChangePtr()) #define PO_ACCESS_REGTYPE_CONST(instance) (*(instance).Ptr()) #define PO_ACCESS_REGTYPE_CONST_PTR(instance) ((instance).Ptr()) // Union specific operations... #define PO_BUILDUNION_REG(reg_type_name, data) (data) #define PO_BUILDUNION_REG_SBL(reg_type_name, data) (data) // Miscellaneous operations... #define PO_REGTYPE_ISVALID(instance) ((instance).Ptr() != NULL) //***************************************************** //* Interface-type (non-handle-type-non-enum) bindings //***************************************************** // Variable declarations... #define PV_IFCTYPE(type_name) type_name // Formal parameter declarations... #define PF_IFCTYPE_IN(type_name) type_name #define PF_IFCTYPE_CH(type_name) type_name& #define PF_IFCTYPELTD_CH(type_name) type_name& // Return type declarations of functions #define PR_IFCTYPE(type_name) type_name // function (const) return #define PR_IFCTYPE_CH(type_name) type_name& // selector (non-const) return // Operations... #define PO_BUILDIFCTYPE(type_name, brktdargs) type_name brktdargs // Instance access operations on interface (small-class types)... #define PO_ACCESS_IFCTYPE(instance) instance #define PO_CHANGE_IFCTYPE(instance) instance // Union specific operations... #define PO_BUILDUNION_IFC(small_type_name, data) _mWrapNonStorable(data, small_type_name) // small classes #define PO_BUILDUNION_BASIC(basic_type_name, data) _mWrapBasic(data, basic_type_name) // builtin basic types //************************************************* //* Interface-type (non-handle-type-enum) bindings //************************************************* // Enerated type variable declaration... #define PV_ENUM(perfect_enum) perfect_enum::_eEnum // Enumeration member access operator... #define PM_ENUM(perfect_enum, enum_val) perfect_enum::enum_val // Union specific operations... #define PO_BUILDUNION_ENUM(enum_type_name, data) _mWrapEnum(data, enum_type_name) #define PO_BUILDUNION_ENUM_SBL(enum_type_name, data) _mWrapStorableEnum(data, enum_type_name) // this will only apply to buitin small classes (including strings) // To-string operation ... #define PO_ENUM_TOSTRING(perfect_enum, enum_val) perfect_enum::_ltoString(enum_val) //************************************************** //* String bindings //************************************************** // Variable declarations... #define PV_STRTYPE _rstring // Formal parameter declarations... #define PF_STRTYPE_IN _rstring #define PF_STRTYPE_CH _rstring& // Operations... // Build a 'Perfect' string from a C string literal #define PO_BUILDSTRTYPE_LIT(c_string) _mString(c_string) // Build a 'Perfect' string from a C string variable #define PO_BUILDSTRTYPE_VAR(c_string) _lString(c_string) // Conversion yielding a C string from a Perfect string valid for use as a function argument only - the memory this allocates // for the converted string will be destroyed when the expression generated by this macro goes out of scope and for this // reson, this convertion macro should NOT be used for returning char* pointers from functions. Use the "PO_CONVERTSTR(..)" // macro instead!!! #define PO_CONVERTSTR_FORARG(perfect_string) (_eCstring(perfect_string).str()) // Conversion operation from Perfect string to C string - This allocates memory (on the 'Perfect' heap) for a copy of the // string and returns a pointer to it, making it the responsibility of the caller to dispose of the memory when the string // is no longer required (use the "PO_FREECONVSTR(..)" macro to do this) ... #define PO_CONVERTSTR(c_string, perfect_string) \ { \ int length = perfect_string._oHash() + 1; \ c_string = static_cast(_eMem::alloc(length * sizeof(_eChar))); \ for (int i = 0; i < static_cast(length) - 1; ++i) { c_string[i] = perfect_string[i]; } \ c_string[length - 1] = '\0'; \ } // Macros to free the memory allocated by a previous "PO_CONVERTSTR(..)" macro call. Not sure which of these versions is the // best - the 2nd one is more convenient, but will cause problems if the c_string contains non-terminating null characters... //#define PO_FREECONVSTR(c_string, perfect_string) _eMem::free(c_string, perfect_string._oHash()) #define PO_FREECONVSTR(c_string) _eMem::free(c_string, strlen(c_string)) // Union specific operations... #define PO_BUILDUNION_STR(data) _mWrapStorable(data, _rstring) //************************************************** //* Heap/ref bindings //************************************************** // Variable declarations... #define PV_HEAPTYPE _eHeap #define PV_REFTYPE(refdObjectType) _eRef< refdObjectType > // Operations... #define PO_BUILDREF(refdObjectType, refdObjectInstance, heapPtr) _eRef< refdObjectType >((refdObjectInstance), (heapPtr)) //************************************************** //* Union bindings //************************************************** #define PV_UNIVUNION _eUnion //************************************************** //* Miscellaneous bindings //************************************************** // Macros to implement operators - we provide these because some (most) operators are generated as // functions in the target C++, and thus have special names ... // UNARY #define UO_HASH(lhs) (lhs)._oHash() #define UO_PLUS(lhs) (lhs).operator+() #define UO_MINUS(lhs) (lhs).operator-() #define UO_LESSTHAN(lhs) (lhs)._oPred() #define UO_GREATERTHAN(lhs) (lhs)._oSucc() // BINARY #define BO_CARET(lhs, rhs) (lhs)._oExp(rhs) #define BO_STARSTAR(lhs, rhs) (lhs)._oStarStar(rhs) #define BO_PLUSPLUS(lhs, rhs) (lhs)._oPlusPlus(rhs) #define BO_MINUSMINUS(lhs, rhs) (lhs)._oMinusMinus(rhs) #define BO_HASH(lhs, rhs) (lhs)._oHash(rhs) #define BO_PLUS(lhs, rhs) (lhs).operator+(rhs) #define BO_MINUS(lhs, rhs) (lhs).operator-(rhs) #define BO_STAR(lhs, rhs) (lhs).operator*(rhs) #define BO_SLASH(lhs, rhs) (lhs)._oDiv(rhs) #define BO_PERCENT(lhs, rhs) (lhs)._oMod(rhs) #define BO_LESSLESS(lhs, rhs) (lhs)._oLessLess(rhs) #define BO_LESSLESSEQ(lhs, rhs) (lhs)._oLessLessEq(rhs) #define BO_IN(lhs, rhs) (rhs)._ovIn(lhs) #define BO_RANK(lhs, rhs) (lhs)._oRank(rhs) #define BO_DOTDOT(lhs, rhs) (lhs)._oRange(rhs) // Member declaration introduction macros (for readability only)... #define PM_SCHEMA void #define PM_FUNCTION //---------------------------------------------------------------------- // union of string or other small class with anything else // union of regular class with at least one other class (of any type) //---------------------------------------------------------------------- // Operators to build universal unions for holding various types (string, regular (handle), [non]storable interface (small) ... #define PO_BUILDUNION_UNIV_STR(data) _mWrapStorable(data, _rstring) #define PO_BUILDUNION_UNIV_REG(data) (static_cast(data.Ptr())) #define PO_BUILDUNION_UNIV_IFC(data, type_of_data) _mWrapNonstorable(data, type_of_data) #define PO_BUILDUNION_UNIV_IFC_SBL(data, type_of_data) _mWrapStorable(data, type_of_data) // Constant representing the void type (for the 'null' value) of the universal union ... #define PC_UNIVUNION_VOIDVAL (_eUnion(_mNullPtr(_eAny))).Ptr() //---------------------------------------------------------------------- // union of regular class with void //---------------------------------------------------------------------- #define PO_BUILDUNION_SMPL_REG(data) _eUnion((data).Ptr()) #define PT_SMPLUNION_ISVOID(variable_name) ((variable_name).Ptr() == NULL) #define PT_SMPLUNION_NOTVOID(variable_name) ((variable_name).Ptr() != NULL) #define PC_SMPLUNION_VOIDVAL(type_of_nonvoid_part) _mNullPtr(type_of_nonvoid_part) // Binding for use when we want to call the non-const (change) version of a Perfect selector (remember that 2 C++ functions // get generated for a proper (ie. not an access) selector, the non-const version having its name pre-fixed with '_s' ... #define SELECTOR_CALL(selName) _s##selName // Member actual parameter conversion bindings (required due to parameter code-generation rules) ... // * Use these whenever calling a Perfect function with any non-builtin Perfect type, eg. when calling a function // * that takes a non-modifiable regular-type (or non-modifiable union) with a regular-type or union we would pass // * the actual parameter via the 'PA_NONWRTBL_REGTYPE(..)' macro ... #define PA_NONWRTBL_REGTYPE(param) ((param).Ptr()) #define PA_LTDWRTBL_REGTYPE(param) ((param).ChangePtr()) #define PA_FLYWRTBL_REGTYPE(param) (param) // #define PA_NONWRTBL_IFCTYPE(param) (param) #define PA_LTDWRTBL_IFCTYPE(param) (param) #define PA_FLYWRTBL_IFCTYPE(param) (param) /* HELP WITH MACRO NAMES ... * PA_ = Perfect actual parameter conversion (use when calling a Perfect function with Perfect data) * PC_ = Perfect constant * PF_ = Perfect formal-parameter type * PM_ = Perfect class member macros * PO_ = Perfect operator ??? * PR_ = Perfect return value generator * PT_ = Perfect data-test macro * PV_ = Perfect variable declaration * BO_ = Perfect binary operator * UO_ = Perfect unary operator */ // End.