user_guide:extend:cpp_type_binding

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
reference:cpp_type_binding [2012/03/30 16:25] – created gawrilowuser_guide:extend:cpp_type_binding [2019/01/29 21:46] (current) – external edit 127.0.0.1
Line 1: Line 1:
-====== Property Type Bindings to C++ Classes ====== +====== Property Type Binding to C++ Classes ====== 
-This page contains the complete list of attributes of [[rulefiles#type_definitions|property type declarations]] controlling the details of the interplay between the property type being visible on the perl side and the hidden C++ class.+Declaring a property type with ''c++'' attribute means that the real value of each data instance of this type will be kept in a proper C++ object rather than as a bunch of perl primitive items like scalars or lists.  The whole access to the data is then implemented by operator overloading, C++ method wrapping, and, in the case of C++ container types, by the standard perl technique of tied arrays and hash maps
  
-====== Glue code generation ====== +The first and main goal of preserving the C++ objects under the hood is to avoid performance lost: when a C++ client creates a "big" object property, e.g. a coordinate matrix, it is obviously born as a C++ object, a Matrix<Rational> or such.  When the client terminates, this matrix has to be passed back to the perl world.  It could be converted once to a pure perl representation, say, to a nested list of lists, but later, when another C++ client asks for this property, it will again want to fill it into its own Matrix<Rational> object, thus starting the next round of conversions.  Having the original Matrix<Rational> preserved in the property eliminates the needs in any conversions at all: the client asking for a matrix gets the const reference to the original data and can work with it directly.  Certainly, this mechanism applies not only for "big" object properties, but wherever the C++ objects are passed through the perl--C++ "membrane", in particular, when catching the return value of a wrapped C++ function. 
-  ? ''%%name => "class_name"%%''+ 
 +For experts in perl guts: the C++ objects are stored in the so called magic attachment.  For C++ classes with container or composite (tuple) semantics the base perl type is an array (and the magic is an extension of that for tied arrays), for associative containers it is a hash map (dito for tied hash maps), otherwise it is a scalar.  Actually, the value stored in the magic attachment is a copy of the (usually local) C++ object created by the client.  It does not, however, constitute a serious performance problem, since the copy constructors of almost all voluminous data types in the Polymake Template Library merely clone a smart pointer.  Using STL containers would yield completely different performance figures, but they are currently not bound to any property types in polymake. 
 + 
 +===== Mapping between C++ classes and property types ===== 
 +A C++ object passed back to the perl side is preserved in the magic storage if and only if its class is made known to polymake by binding it or one of its ancestors (in the C++ class hierarchy) to a property type.  Transient objects (e.g. MatrixMinor) can also be preserved if they belong to a generic family (in this example GenericMatrix) whose canonical representative is known to polymake (in this example either Matrix or SparseMatrix, depending on the provenience of the minor).  However, when a transient C++ object is assigned to a property of a "big" object, the value stored in the magic will be of a persi 
 + 
 +Note that derivation among property types (being declared in the rulefiles) does not interfere with underlying C++ classes.  For example, the property type SparseMatrix is defined as derived from Matrix, which allows to save a lot of re-declarations of common methods like ''rows'', ''cols'', or ''minor'', and also to describe any C++ function template accepting a GenericMatrix argument as accepting a Matrix on the perl side.  But the corresponding C++ classes Matrix and SparseMatrix are completely independent.  To the contrary, a property type derived from another one bound to a C++ class should be in its turn bound to a different C++ class, otherwise it will never be used, because all C++ clients will automatically map the underlying C++ class to the base property type. 
 + 
 +===== Attributes in property type declarations ===== 
 + 
 +==== Glue code generation ==== 
 +  ? ''%%name => "%%''class_name''%%"%%''
   :: Specifies the name of the C++ class.  The //class_name// must be a valid C++ type expression, fully qualified with namespace names if needed.  As an exception, the namespace ''polymake'' (for types from the Polymake Template Library) and the namespace of the current application ''polymake::APPNAME'' can be omitted.   :: Specifies the name of the C++ class.  The //class_name// must be a valid C++ type expression, fully qualified with namespace names if needed.  As an exception, the namespace ''polymake'' (for types from the Polymake Template Library) and the namespace of the current application ''polymake::APPNAME'' can be omitted.
   .. If this attribute is omitted, the C++ class name is supposed to be identical to the name of the property type being defined and to be defined in the ''polymake'' namespace.   .. If this attribute is omitted, the C++ class name is supposed to be identical to the name of the property type being defined and to be defined in the ''polymake'' namespace.
   .. If the property type is defined as a parameterized type, the corresponding C++ type is supposed to a class template as well, having a congruent list of type parameters.   .. If the property type is defined as a parameterized type, the corresponding C++ type is supposed to a class template as well, having a congruent list of type parameters.
-  ? ''%%name => "class_name<type, ...>"%%''+  ? ''%%name => "%%''class_name''<'' type, ... ''%%>"%%''
   :: Specifies the C++ type expression involving class templates, with the number or order of type parameters not exactly matching the property type definition.  //type// can be either a constant type expression or a placeholder ''%N'' referring to the parameters of the property type, with //N// starting with 1.   :: Specifies the C++ type expression involving class templates, with the number or order of type parameters not exactly matching the property type definition.  //type// can be either a constant type expression or a placeholder ''%N'' referring to the parameters of the property type, with //N// starting with 1.
   ? ''%%name => \&sub%%''   ? ''%%name => \&sub%%''
   :: Specifies a subroutine synthesizing the C++ type expression.  This form is used in especially complicated cases of parameterized type mapping.  The subroutine is called with a list of C++ type names corresponding to the type parameters of the concrete instance; if the subroutine is declared as ''method'', it will also get the property type descriptor as a leading argument.   :: Specifies a subroutine synthesizing the C++ type expression.  This form is used in especially complicated cases of parameterized type mapping.  The subroutine is called with a list of C++ type names corresponding to the type parameters of the concrete instance; if the subroutine is declared as ''method'', it will also get the property type descriptor as a leading argument.
-  ? ''%%builtin => "type_name"%%''+  ? ''%%builtin => "%%''type_name''%%"%%''
   :: Tells that the values of this property type are kept as plain perl entities (numbers, strings, anonymous references, ...) without C++ objects lurking in the magic storage, but when such a value is passed to a C++ function, the glue code must be generated as to accept the specified C++ type.  There is a very limited list of property types declared with this attribute, all of them residing in ''apps/common/rules/basic_types''.   :: Tells that the values of this property type are kept as plain perl entities (numbers, strings, anonymous references, ...) without C++ objects lurking in the magic storage, but when such a value is passed to a C++ function, the glue code must be generated as to accept the specified C++ type.  There is a very limited list of property types declared with this attribute, all of them residing in ''apps/common/rules/basic_types''.
-  ? ''%%builtin => enum {%%'' name, ... ''%%}%%''+  ? ''%%builtin => enum {%%'' name, ... ''}''
   :: Introduces an enumeration type and named constants.   :: Introduces an enumeration type and named constants.
   ? ''%%builtin => \&sub%%''   ? ''%%builtin => \&sub%%''
   :: Specifies a subroutine deciding for the given instance of a parameterized property type whether the values should be stored as plain perl entities or as C++ objects in the magic storage.  The subroutine is called at the first occurrence of a concrete instance with the property type descriptor as a single argument.   :: Specifies a subroutine deciding for the given instance of a parameterized property type whether the values should be stored as plain perl entities or as C++ objects in the magic storage.  The subroutine is called at the first occurrence of a concrete instance with the property type descriptor as a single argument.
-  ? ''%%special => "class_name"%%''+  ? ''%%special => "%%''class_name''%%"%%''
   :: Tells that this property type is of limited use and should not be equipped with constructors, overloaded operators, and other comforts.  This attribute is used, for example, for pure type tags like ''Undirected'' or ''Symmetric''.   :: Tells that this property type is of limited use and should not be equipped with constructors, overloaded operators, and other comforts.  This attribute is used, for example, for pure type tags like ''Undirected'' or ''Symmetric''.
-  ? ''%%include => [ "header_file", ... ]%%''+  ? ''%%include => [ "%%''header file''%%"%%'', ... '']''
   :: Lists the header files to be included into the auto-generated glue code.  For built-in types like ''int'' this list can be empty, otherwise it should contain at least the header file where the C++ class is defined.  Further headers may be added automatically to the glue code for class templates depending on the parameters occurring in concrete instantiations.   :: Lists the header files to be included into the auto-generated glue code.  For built-in types like ''int'' this list can be empty, otherwise it should contain at least the header file where the C++ class is defined.  Further headers may be added automatically to the glue code for class templates depending on the parameters occurring in concrete instantiations.
      
-====== Method generation ======+==== Method generation ====
   ? ''%%default_constructor => 0%%''   ? ''%%default_constructor => 0%%''
   :: Suppresses automatic creation of standard constructors.  Usually, all property types not declared with ''builtin'' or ''special'' attributes are automatically equipped with the following standard constructors:   :: Suppresses automatic creation of standard constructors.  Usually, all property types not declared with ''builtin'' or ''special'' attributes are automatically equipped with the following standard constructors:
Line 30: Line 41:
     * structure constructor for composite types: ''%%new Type(%%''init1, init2, ...''%%)%%''     * structure constructor for composite types: ''%%new Type(%%''init1, init2, ...''%%)%%''
   .. If the C++ class bound to it does not support the corresponding operation, for example, it is lacking the default constructor or the input ''%%operator >>%%'', you should suppress the standard constructors and provide appropriate specializations of ''method construct'' in the [[rulefiles#property_type_scope_definitions|type definition scope]].   .. If the C++ class bound to it does not support the corresponding operation, for example, it is lacking the default constructor or the input ''%%operator >>%%'', you should suppress the standard constructors and provide appropriate specializations of ''method construct'' in the [[rulefiles#property_type_scope_definitions|type definition scope]].
-  ? ''%%fields => [ "%%''name''%%"%%'', ... ''%%]%%''+  ? ''%%fields => [ "%%''name''%%"%%'', ... '']''
   :: For a composite type, creates methods with given names accessing the members (aka fields of a structure).  The order of the names must correspond to the order of type declarations in the specialization of ''%%pm::spec_object_traits<Type>::elements%%'' .   :: For a composite type, creates methods with given names accessing the members (aka fields of a structure).  The order of the names must correspond to the order of type declarations in the specialization of ''%%pm::spec_object_traits<Type>::elements%%'' .
   ? ''%%operators => "%%''overloaded operators''%%"%%''   ? ''%%operators => "%%''overloaded operators''%%"%%''
Line 42: Line 53:
     ? op_symbol''('' [[polymorphic|function header]] '')''     ? op_symbol''('' [[polymorphic|function header]] '')''
     :: Maps the operator to a C++ function with given name and signature.  [[polymorphic#attributes|Trailing attributes]] ''method'', ''wary'', ''lvalue'' can be specified if the function is implemented as a method of the C++ class.     :: Maps the operator to a C++ function with given name and signature.  [[polymorphic#attributes|Trailing attributes]] ''method'', ''wary'', ''lvalue'' can be specified if the function is implemented as a method of the C++ class.
 +    
 +===== Abstract property types =====
 +Some property types are introduced solely for wrapping a vast bunch of unrelated C++ classes under a common perl interface.  For example, all iterators have some common methods like dereferencing and validity check, but they don't belong to a single generic family nor are they derived from a common base class, so that no automatic type detection could help here.  In such cases, an abstract property type is introduced as a parameterized type with a special wildcard symbol in lieu of a parameter list:
 +  declare property_type Iterator<*> : c++;
 +Then all wrapped C++ functions returning an iterator must be explicitly declared as such:
 +  function entire(*) : c++ : returns(Iterator<*>);
 +An abstract property type can't be used in definitions of "big" object properties, nor in constructor calls like ''new Iterator(...)''.
  • user_guide/extend/cpp_type_binding.1333124719.txt.gz
  • Last modified: 2014/01/03 15:45
  • (external edit)