📄 stl.hhf
字号:
//// method getAllocSize; @returns( "eax" );// Returns the number of bytes allocated for the data in the// vector (in EAX). Operates in O(1) time.//// method getDataSize; @returns( "eax" );// Returns the number of bytes allocated for the data in actual// use in the vector. Operates in O(1) time.//// method clear;// Removes all elements from the vector. Operates in O(1) time.//// iterator forEachElement;// Iterates through the vector from beginning to end and on each// iteration returns a pointer to the current vector element in// the EAX register.//// iterator rForEachElement;// As above, except it iterates through the vector from the end// back to the beginning.//// method appendRef( var toAppend:vectorType );// Appends the object "toAppend" (passed by reference) to the end// of the vector. Operates in O(1) time.//// method appendVal( toAppend:vectorType );// Appends the object "toAppend" (passed by value) to the end// of the vector. Operates in O(1) time.//// method prependRef( var toPrepend:vectorType );// Inserts the object "toPrepend" at the beginning of the list.// toPrepend is passed by reference (great for large vectorType// objects). Operates in O(n) time.//// method prependVal( toPrepend:vectorType );// Inserts the object "toPrepend" at the beginning of the list.// toPrepend is passed by value (great for smaller vectorType// objects). Operates in O(n) time.//// method insertRef( var toInsert:vectorType; posn:uns32 );// Inserts the object "toInsert" in front the the posnTH object.// toInsert is passed by reference (great for large vectorType// objects). Operates in O(n) time. Note that items are indexed// starting with position zero. If posn is greater than the// number of vector elements, this method appends the object// to the end of the vector.//// method insertVal( toInsert:vectorType; posn:uns32 );// Inserts the object "toInsert" in front the the posnTH object.// toInsert is passed by value (great for small vectorType// objects). Operates in O(n) time. Note that items are indexed// starting with position zero. If posn is greater than the// number of vector elements, this method appends the object// to the end of the vector.//// method remove( n:uns32 );// Removes the object at posn "n" from the vector. If n is greater// than the number of vector elements, this method has no effect.// Operates in O(n) time.//// method remove_first;// Removes the first element from the vector. // Operates in O(n) time.//// method remove_last;// Removes the last element from the vector. // Operates in O(1) time.//// Cursor methods:// Note: you should not assume that there is a correspondance// between cursors and pointers to vector elements. Though this// may be the actual implementation, subclassed vector types// may not guarantee this same implementation. Treat cursors as// opaque (private) types that are used internally by vector methods.//// method nextCursor( var cursor:cursorType );// Modifies the cursor object passed by reference so that it// points at the next element of the vector (relative to where// it currently points). If this would advance the cursor beyond// the end of the vector, this method sets "cursor" to point at// just beyond the end of the vector (i.e., endCursor). Operates// in O(1) time.//// method prevCursor( var cursor:cursorType );// Modifies the cursor object passed by reference so that it// points at the previous element of the vector (relative to where// it currently points). If this would advance the cursor before// the beginning of the vector, this method sets "cursor" to point at// the start of the vector (i.e., beginCursor). Operates in O(1)// time.//// method beginCursor( var cursor:cursorType );// Points the cursor object passed by reference at the start of// the vector. Operates in O(1) time.//// method endCursor( var cursor:cursorType );// Points the cursor object passed by reference to the point// just beyond the end of the vector. Operates in O(1) time.//// method front; @returns( "eax" );// Returns a cursor value in EAX that corresponds to the start// of the vector. Operates in O(1) time.//// method back; @returns( "eax" );// Returns a cursor value in EAX that corresponds to the end// of the vector (points beyond the end of the vector). Operates// in O(1) time.//// method atBack( cursor:cursorType ); @returns( "@z" );// Compares the cursor passed by reference against the end of// the vector and sets the Z flag if the cursor is at the end// of the vector. Operates in O(1) time.//// method atFront( cursor:cursorType ); @returns( "@z" );// Compares the cursor passed by reference against the beginning// of the vector and sets the Z flag if the cursor as at the// start of the vector. Operates in O(1) time.//// method at( cursor:cursorType in eax ); @returns( "eax" );// Returns a pointer (in EAX) to the vector element data referenced by// the cursor passed by reference. You should use this method to// convert a cursor to a data element pointer and not assume that// cursors and data element pointers are equivalent. Operates in// O(1) time.//// method getAt( cursor:cursorType; var dest:vectorType );// Copies the data at the vector element referenced by the cursor// you pass as the first argument to the location specified by// the second argument. Operates in O(1) time relative to n (the// number of vector elements).//// method insertAtVal( toInsert:vectorType; cursor:cursorType );// Inserts the value "toInsert" before the item referenced by// the cursor passed as the second argument. Value (toInsert) is// passed by value, making this routine good for small vectorType// objects. Operates in O(n) time.//// method insertAtRef( var toInsert:vectorType; cursor:cursorType );// Inserts the value "toInsert" before the item referenced by// the cursor passed as the second argument. Value (toInsert) is// passed by reference, making this routine good for large vectorType// objects. Operates in O(n) time.//// method removeAt( cursor:cursorType );// Removes the vector entry referenced by the cursor passed// as the argument. Operates in O(n) time.//// method getRef( n:uns32 in eax ); @returns( "eax" );// Computes and returns the address (in EAX) of the nTH element// in the vector. Operates in O(1) time.//// method getVal( n:uns32; var dest:vectorType );// Copies the value in the nTH vector element to the location// specified by the second parameter.//// method swapObj( var obj:symbol );// Swaps the current vector object (THIS) with the one specified// by the parameter. This routine operates in O(1) time and is// very fast.//// method swapElements( var first:cursorType; second:cursorType );// Swaps two vector elements (not necessarily in the same vector).// Operates in O(1) time.//// method isEqual// ( // var left:vectorType; // var right:vectorType // ); @returns( "al" );//// Compares two vectorType objects that are passed by reference// and returns AL=1 (and clears the Z flag) if they are equal.// // method isLess// ( // var left:vectorType; // var right:vectorType // ); @returns( "al" );//// Compares two vectorType objects that are passed by reference// and returns AL=1 (and clears the Z flag) if left < right.// // // method isLessEqual// ( // var left:vectorType; // var right:vectorType // ); @returns( "al" );//// Compares two vectorType objects that are passed by reference// and returns AL=1 (and clears the Z flag) if left <= right.// // Note: you can simulate <>, >, and >= by inverting the value in AL// upon return from the above three routines. // // method toString; @external( outputFunc[0] );// (Optional implementation) Converts an object of type "symbol"// to a string for use by output routines like stdout.put.////// Note class _vector is a generic helper class for the vector template// that is used to reduce the amount of code generated for multiple vector// types.#macro vector( rawVectorType, specificTraits[] ): symbol, vectorType, section, cursorType, ptrType, temp; @forward( symbol ); vectorType : rawVectorType; ?section := @section; #if( (section & @global:hla.inType) <> @global:hla.inType ) #error( "VECTOR declarations may only appear in a TYPE section" ) #else // Create a cursor type for this class: ?temp :string := @string( @text( symbol ) ); ?cursorType :string := temp + "_cursor"; ?cursorType :text := cursorType; cursorType :pointer to vectorType; // Create a pointer type for this class: ?ptrType :string := "p_" + temp; ?ptrType :text := ptrType; ptrType :pointer to symbol; // Create the actual class: symbol: class inherits( stl._vector ); // Set up the default capabilities for a vector: val hierarchy_c := hierarchy_c | stl.isVector_c; capabilities_c := capabilities_c #if( @isClass( vectorType )) | stl.elementsAreObjects_c #endif | stl.supportsAppend_c | stl.supportsPrepend_c | stl.supportsInsert_c | stl.supportsRemove_c | stl.supportsSwap_c | stl.supportsForeach_c | stl.supportsrForeach_c | stl.supportsCursor_c | stl.supportsElementSwap_c | stl.supportsObjSwap_c; // Okay, process any specific capabilities provided in // the vector declaration: capabilities_c := stl.parseCapabilities ( capabilities_c, specificTraits ); // Set up the default performance traits: performance_c := performance_c #if( @size( vectorType ) <= 16 ) | stl.fastElementSwap_c #endif | stl.fastAppend_c | stl.fastSwap_c; // Okay, process any specific performance traits // provided in the vector declaration: performance_c := stl.parsePerformance ( performance_c, specificTraits ); // Just as a safety net, let's verify that all // the user-specified traits are valid: stl.checkTraits ( specificTraits, [[stl.performanceNames],[stl.capabilityNames]] ); readonly typeName_ro :string := temp; // Public entities begin here: // // Constructor and destructor. // Note that all vector types have a constructor and destructor procedure create( numElements:uns32 ); // Note: inherits destructor from arrayContainer class // method destroy; // iterators: #if( (symbol.capabilities_c & stl.supportsForeach_c) <> 0 ) iterator forEachElement; #endif #if( (symbol.capabilities_c & stl.supportsrForeach_c) <> 0 ) iterator rForEachElement; #endif // Element append, insert, and removal: #if( (symbol.capabilities_c & stl.supportsAppend_c) <> 0 ) method appendRef( var toAppend:vectorType ); method appendVal( toAppend:vectorType ); #endif #if( (symbol.capabilities_c & stl.supportsPrepend_c) <> 0 ) method prependRef( var toPrepend:vectorType ); method prependVal( toPrepend:vectorType ); #endif #if( (symbol.capabilities_c & stl.supportsInsert_c) <> 0 ) method insertRef( var toInsert:vectorType; posn:uns32 ); method insertVal( toInsert:vectorType; posn:uns32 ); #endif #if( (symbol.capabilities_c & stl.supportsRemove_c) <> 0 ) method remove( n:uns32 ); method remove_first; method remove_last; #endif #if( (symbol.capabilities_c & stl.supportsCursor_c) <> 0 ) // Cursor manipulation routines: method nextCursor( var cursor:cursorType ); method prevCursor( var cursor:cursorType ); method beginCursor( var cursor:cursorType ); method endCursor( var cursor:cursorType ); method front; @returns( "eax" ); method back; @returns( "eax" ); method atBack( cursor:cursorType ); @returns( "@z" ); method atFront( cursor:cursorType ); @returns( "@z" ); method at( cursor:cursorType in eax ); @returns( "eax" ); method atIndex( n:uns32 in eax ); @returns( "eax" ); method getAt( cursor:cursorType; var dest:vectorType ); #if( (symbol.capabilities_c & stl.supportsInsert_c) <> 0 ) method insertAtVal ( toInsert:vectorType; cursor:cursorType ); method insertAtRef ( var toInsert:vectorType; cursor:cursorType ); #endif #if( (symbol.capabilities_c & stl.supportsRemove_c) <> 0 ) method removeAt( cursor:cursorType ); #endif #endif // Accessor methods: method getRef( n:uns32 in eax ); @returns( "eax" ); method getVal( n:uns32; var dest:vectorType ); // Element & object swapping: #if( (symbol.capabilities_c & stl.supportsObjSwap_c) <> 0 ) method swapObj( var obj:symbol ); #endif #if( (symbol.capabilities_c & stl.supportsElementSwap_c) <> 0 ) method swapElements ( first:cursorType; second:cursorType ); #endif // Comparisons: #if( (capabilities_c & stl.supportsCompare_c) <> 0 ) method isEqual ( var left:vectorType; var right:vectorType ); @returns( "al" ); method isLess ( var left:vectorType; var right:vectorType ); @returns( "al" ); method isLessEqual ( var left:vectorType; var right:vectorType ); @returns( "al" ); #endif // Output method #if( (capabilities_c & stl.supportsOutput_c) <> 0 ) override method toString; #endif endclass; // Emit the VMT for this class: static vmt( stl.symbol ); // Object constructor. // If called with ESI = 0 (class constructor call) then // this routine allocates storage for the object itself // and returns a pointer to that object in ESI. For all // objects, this code also allocates storage for a vector // with "numElements" entries. procedure symbol.create( numElements:uns32 ); @nodisplay; @noalignstack; begin create; push( eax ); xor( eax, eax ); // Init isAlloc to false. if( esi = 0 ) then mem.alloc( @size( symbol )); mov( eax, esi ); mov( true, al ); // Set isAlloc true. endif; mov( al, this.isAlloc ); // Initialize the VMT pointer: mov( &symbol._VMT_, this._pVMT_ ); // Allocate storage for the vector and initialize // the array fields: this.createArray( numElements, @size( vectorType )); // Runtime information: // Begin by initializing the standard boolean variables with // their respective values for a vector. mov( symbol.capabilities_c, this.capabilities ); mov( symbol.performance_c, this.performance ); mov( symbol.hierarchy_c, this.hierarchy ); // Other vector specific-initialization: lea( eax, "vector" ); mov( eax, this.containerName ); mov( symbol.typeName_ro, eax ); mov( eax, this.typeName ); pop( eax ); end create; #if( (symbol.capabilities_c & stl.supportsAppend_c) <> 0 ) // appendRef- // Appends a new element to the end of the array. // The value passed as the argument is passed by reference. // You should use this append function when the vector element // type is large. method symbol.appendRef( var toAppend:vectorType ); @nodisplay; @noalignstack; begin appendRef; // Begin by making sure we've got enough room in the // data array to hold the new object: pushfd(); push( eax ); push( ecx ); push( edi ); cld(); this._append ( #{ push( toAppend ); }#, @size( vectorType ) ); pop( edi ); pop( ecx ); pop( eax ); popfd(); end appendRef; // appendVal- // Appends a new element to the end of the array. // The value passed as the argument is passed by value. // You should use this append function when the vector element // type is small (typically 16 bytes or less). method symbol.appendVal( toAppend:vectorType ); @nodisplay; @noalignstack; begin appendVal; // Begin by making sure we've got enough room in the // data array to hold the new object: pushfd(); push( eax ); push( ecx ); push( edi ); cld(); this._append ( #{ lea( eax, toAppend ); push( eax ); }#, @size( vectorType ) ); pop( edi ); pop( ecx ); pop( eax ); popfd(); end appendVal; #endif #if( (symbol.capabilities_c & stl.supportsPrepend_c) <> 0 ) // prependRef- // // Inserts an array element (toInsert) at the beginning of // the array. // // prependRef passes toInsert by reference, so you should use this // function to insert large objects into the array. method symbol.prependRef( var toPrepend:vectorType ); @nodisplay; @noalignstack; begin prependRef; push( eax ); push( ecx ); pushfd(); push( edi ); this._insert ( #{ push( toPrepend ); }#, this.data, @size( vectorType ) ); pop( edi ); popfd(); pop( ecx ); pop( eax ); end prependRef; // prependVal- // // Inserts an array element (toInsert) at the beginning of // the array.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -