Search the Community
Showing results for tags 'enumerator'.
Found 2 results
-
Suggestion of naming convention for enumerators
JohnLM posted a topic in Algorithms, Data Structures and Class Design
Specs: Win7, Delphi 11.2, VCL I wrote some functions to convert string to byte and byte to string. These functions work. For testing, I added several tbuttons and a memo on the form and began testing my ideas shown below. function str2byte(str: string): TBytes; begin setlength(str,length(str)); result := TEncoding.utf8.getbytes(str); end; function byte2str(byt: TBytes): string; begin result := TEncoding.ascii.getstring(byt); end; usage: procedure TForm1.Button1Click(Sender: TObject); var strs: string; bytes: TBytes; begin bytes := str2byte('ABC'); // string strs := byte2str(bytes); // bytes memo1.Lines.Add(byte2str(bytes)); // show it strs := byte2str([68,69,70]); // bytes bytes := str2byte(strs); // string memo1.Lines.Add(byte2str(bytes)); // show it end; Now, I'd like to extend that to include an additional parameter to the encoding format (ansi, ascii, utf-16-big-endian unicode, utf-16 unicode, utf-7 and utf-8) as found here: https://docwiki.embarcadero.com/Libraries/Alexandria/en/System.SysUtils.TEncoding (And then later, possibly extend upon it by building a class component of it (and other library functions/procedures that I build)). The issue I am having now is how to give the parameters their name. I do not know if there are already built-in types for these and don't want to cause issues later on. But so far, I thought about using these: (_ansi, _ascii, _utf7, _utf8, _utf16be and _utf16u). Or, maybe create an enumerated list, i.e., type TMyEncoding = (_ansi, _ascii, _utf7, _utf8, _utf16be, _utf16u); And rewriting the above output snippet: type TMyEncoding = (_ansi, _ascii, _utf7, _utf8, _utf16be, _utf16u); function _byte2str(byt: TBytes; enc: TMyEncoding): string; begin case integer(enc) of 0: result := TEncoding.ascii.getstring(byt); 1: result := TEncoding.ansi.getstring(byt); 2: result := TEncoding.utf7.getstring(byt); 3: result := TEncoding.utf8.getstring(byt); // ... end; end; procedure TForm1.Button4Click(Sender: TObject); var strs: string; bytes: TBytes; begin bytes := str2byte('_ansi'); // string strs := _byte2str(bytes,_ansi); // bytes memo1.Lines.Add(_byte2str(bytes,_ansi)); // show it // strs := byte2str([68,69,70]); // bytes // bytes := str2byte(strs); // string // memo1.Lines.Add(byte2str(bytes)); // show it end; So I am looking for some advice/suggestions on how to implement the names for each of the encodings that will not interfer with Delphi's built-in names. TIA. -
Generics: weird problem with backward running enumerator
A.M. Hoornweg posted a topic in Algorithms, Data Structures and Class Design
Hello all, I'm stumbling on an unexpected generics-related problem here (Delphi XE). I'm trying to implement a backward-running enumerator for a generic tList<T>. I believe I did everything correctly but still the enumerator runs forward unless I make a modification that really shouldn't be necessary. TYPE tListEnumReversed<T> = CLASS(tEnumerator<T>) PROTECTED fowner: tlist<T>; fListIndex: integer; FUNCTION DoGetCurrent: T; OVERRIDE; FUNCTION DoMoveNext: Boolean; OVERRIDE; PUBLIC CONSTRUCTOR Create(owner: tlist<T>); END; tListReversed<T> = CLASS(tlist<T>) PROTECTED FUNCTION DoGetEnumerator: tEnumerator<T>; OVERRIDE; END; CONSTRUCTOR tListEnumReversed<T>.Create(owner: tlist<T>); BEGIN fowner := owner; fListIndex := owner.count; END; FUNCTION tListEnumReversed<T>.DoGetCurrent: T; BEGIN Result := fowner[fListIndex]; END; FUNCTION tListEnumReversed<T>.DoMoveNext: Boolean; BEGIN Result := fListIndex > 0; IF Result THEN Dec(fListIndex); END; FUNCTION tListReversed<T>.DoGetEnumerator: tEnumerator<T>; BEGIN Result := tListEnumReversed<T>.Create(Self); END; This is the code I used for testing: ... Var t:tListReversed<Integer>; i:integer; begin t:=tListReversed<Integer>.Create; t.Add(1); t.Add(2); t.Add(3); For i in T do memo1.lines.add(inttostr(i)) t.free; end; The weird thing is, the code runs correctly if I make the following change.... And I have literally no idea why that is the case! As far as I can see, the base class tEnumerable<T> already has a method GetEnumerator which should call my overridden virtual Method DoGetEnumerator. What am I missing here ??? tListReversed<T> = CLASS(tlist<T>) PROTECTED FUNCTION DoGetEnumerator: tEnumerator<T>; OVERRIDE; PUBLIC FUNCTION GetEnumerator: TEnumerator<T>; END; ... function tListReversed<T>.GetEnumerator: TEnumerator<T>; begin result:=DoGetEnumerator; end;