Record helpers on built in types?

classic Classic list List threaded Threaded
27 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Record helpers on built in types?

Anthony Walter-3
I tried this out today on FPC fixes_3_0 and was surprised to see it worked:

type
  StringHelper = record helper for string
  private
    function GetLength: Integer;
  procedure SetLength(Value: Integer);
    function GetIsEmpty: Boolean;
    function GetIsWhitespace: Boolean;
  public
    function BeginsWith(const S: string): Boolean;
    function EndsWith(const S: string): Boolean;
    function Trim: string;
    property Length: Integer read GetLength write SetLength;
    property IsEmpty: Boolean read GetIsEmpty;
    property IsWhitespace: Boolean read GetIsWhitespace;
  end;

I love this and would like to know if this is going to be an officially supported feature and can I depend on it to work going forward?

I wrote a string library which is maybe 10x faster for searching, replacing, trimming strings than the default RTL functions and was considering moving them and other add-ons to record helper properties and methods as above.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
I hit send before doing more research. I found this:


"In theory they could be extended to support interfaces, objects or even primitive types as well (although the latter would need bigger adjustments inside the compiler).".

If would seem as if the latter, a big adjustment, was already made. Is it official then?

Also, what are "[hint modifiers];" at the end of the syntax listing? Could I get a few examples of hint modifiers of a class/record helper?

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
More information.

It seems code tools doesn't understand class or record helpers when it come to code insight.

If I type "MyString." and press alt space, I actually receive a code tools "Illegal qualifier . found" error and the entire line highlights red. 

Interestingly, if I define a "TPointHelper = record record helper for TPoint", type "MyPoint." and press alt space nothing happens. I get no insight into my extension proeprties and methods, but I don't get a big honking red error line.

If the code insight person could implement proper insight on helpers, I'd be so grateful! Thanks.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

silvioprog
On Tue, Feb 17, 2015 at 8:19 PM, Anthony Walter <[hidden email]> wrote:
More information.

It seems code tools doesn't understand class or record helpers when it come to code insight.

If I type "MyString." and press alt space, I actually receive a code tools "Illegal qualifier . found" error and the entire line highlights red. 

Interestingly, if I define a "TPointHelper = record record helper for TPoint", type "MyPoint." and press alt space nothing happens. I get no insight into my extension proeprties and methods, but I don't get a big honking red error line.

If the code insight person could implement proper insight on helpers, I'd be so grateful! Thanks.

Related.






--
Silvio Clécio
My public projects - github.com/silvioprog

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
Ah okay, thanks for that. It looks like everything I mentioned has already been discussed. Carry on.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

silvioprog
On Tue, Feb 17, 2015 at 10:17 PM, Anthony Walter <[hidden email]> wrote:
Ah okay, thanks for that. It looks like everything I mentioned has already been discussed. Carry on.

No problems guy. =)

--
Silvio Clécio
My public projects - github.com/silvioprog

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
If anyone was interested in the subject, here is what I came up with after merging my string centric functions into record helpers:

type
  StringArrayHelper = record helper for StringArray
    { Join a string array into a string using a separator }
    function Join(const Separator: string): string;
  end

{ IntArrayHelper }

  IntArrayHelper = record helper for StringArray
    { Join an int array into a string using a separator }
    function Join(const Separator: string): string;
  end

{ StringHelper }

  StringHelper = record helper for string
  private
    function GetIsEmpty: Boolean;
    function GetIsWhitespace: Boolean;
    function GetIsIdentifier: Boolean;
    function GetIsAttribute: Boolean;
    function GetLength: Integer;
    procedure SetLength(Value: Integer);
  public
    { Repeat a character a given length a into string }
    procedure CharInto(C: Char; Len: Integer);
    { Copy a memory buffer into string }
    procedure CopyInto(P: Pointer; Len: Integer);
    { Inserts a substring at a position into string }
    procedure InsertInto(const SubStr: string; Position: Integer);
    { Returns true if a string matches a case insensitive value }
    function Equals(const Value: string): Boolean; overload;
    { Returns true if a string matches any in a set of case insensitive values }
    function Equals(const Values: array of string): Boolean; overload;
    { Compares two strings optionally ignoring case returning -1 if string comes before
      before value, 1 if string comes after value, ord 0 if string and value are equal }
    function Compare(const Value: string; IgnoreCase: Boolean = False): Integer;
    { Convert a string to uppercase }
    function ToUpper: string;
    { Convert a string to lowercase }
    function ToLower: string;
    { Copies a substring given a start and length }
    function Copy(Start: Integer; Len: Integer = 0): string;
    { Searches a string for a substring optionally ignoring case }
    function IndexOf(const SubStr: string; IgnoreCase: Boolean = False): Integer; overload;
    { Searches a string for a substring from a start position optionally ignoring case }
    function IndexOf(const SubStr: string; Start: Integer; IgnoreCase: Boolean = False): Integer; overload;
    { Returns the number of a substring matches within a string }
    function MatchCount(const SubStr: string; IgnoreCase: Boolean = False): Integer;
    { Returns an array of indices of a substring matches within a string }
    function MatchIndices(const SubStr: string; IgnoreCase: Boolean = False): IntArray;
    { Replaces every instance of a pattern in a string }
    function Replace(const OldPattern, NewPattern: string; IgnoreCase: Boolean = False): string;
    { Replaces the first instance of a pattern in a string }
    function ReplaceOne(const OldPattern, NewPattern: string; IgnoreCase: Boolean = False): string;
    { Replaces everything aftger the first instance of a pattern in a string }
    function ReplaceAfter(const OldPattern, NewPattern: string; IgnoreCase: Boolean = False): string;
    { Trims white space from both sides of a string }
    function Trim: string;
    { Returns the index of a string in a string array or -1 if there is no match }
    function ArrayIndex(const Values: array of string): Integer;
    { Splits a string into a string array using a separator }
    function Split(Separator: string): StringArray;
    { Splits a string into a int array using a separator }
    function SplitInt(const Separator: string): IntArray;
    { Splits a string into a int64 array using a separator }
    function SplitInt64(const S, Separator: string): Int64Array;
    { Returns the first subsection of a string if it were split using a separator }
    function FirstOf(Separator: string): string;
    { Returns the second subsection of a string if it were split using a separator }
    function SecondOf(Separator: string): string;
    { Returns the last subsection of a string if it were split using a separator }
    function LastOf(Separator: string): string;
    { Search a string for a substring optionally ignoring case }
    function Contains(SubStr: string; IgnoreCase: Boolean = False): Boolean;
    { Returns true if a string begins with a substring while optionally ignoring case }
    function BeginsWith(SubStr: string; IgnoreCase: Boolean = False): Boolean;
    { Returns true if a string end with a substring while optionally ignoring case }
    function EndsWith(SubStr: string; IgnoreCase: Boolean = False): Boolean;
    { Returns a string made to fit a given length padded on the left with a character }
    function PadLeft(C: Char; Len: Integer): string;
    { Returns a string made to fit a given length padded on the right with a character }
    function PadRight(C: Char; Len: Integer): string;
    { Returns a string surrounded by quotes if it contains whitespace }
    function Quote: string;
    { Analyze a string and find its line break style }
    function LineBreakStyle: TTextLineBreakStyle;
    { Converts the line break style of a string to a the desired style }
    function AdjustLineBreaks(Style: TTextLineBreakStyle): string; overload;
    { Converts the line break style of a string to the system preferred defined style }
    function AdjustLineBreaks: string; overload;
    { Gets true if a string contains only whitespace characters }
    property IsEmpty: Boolean read GetIsEmpty;
    { Gets true if a string contains only whitespace characters }
    property IsWhitespace: Boolean read GetIsWhitespace;
    { Gets true if a string matches to rules of an identifier }
    property IsIdentifier: Boolean read GetIsIdentifier;
    { Gets true if a string matches to rules of an attribute }
    property IsAttribute: Boolean read GetIsAttribute;
    {  Gets or sets the length allocated for the string }
    property Length: Boolean read GetLength write SetLength;
  end;


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

silvioprog
On Wed, Feb 18, 2015 at 12:13 AM, Anthony Walter <[hidden email]> wrote:
If anyone was interested in the subject, here is what I came up with after merging my string centric functions into record helpers:
[...]

Is it similar to the Delphi XE's StringHelper? If yes, could you send a patch to the bugtracker?

--
Silvio Clécio
My public projects - github.com/silvioprog

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

dmitry boyarintsev
In reply to this post by Anthony Walter-3
On Tue, Feb 17, 2015 at 5:28 PM, Anthony Walter <[hidden email]> wrote:
I wrote a string library which is maybe 10x faster for searching, replacing, trimming strings than the default RTL functions and was considering moving them and other add-ons to record helper properties and methods as above.

How 10x faster is achieved ?

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
In reply to this post by silvioprog
I wasn't aware of XE's string helper, so no. 

But if anyone wants to test my StrFindBuffer and StrFindBufferI to gauge their performance against similar RTL library routines, I believe you'll find they are significantly faster. As a consequence all other dependent functions (IndexOf, Match, Replace, Split, and more) would be significantly faster as well.

Here are copies of the relevant code:




_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
In reply to this post by dmitry boyarintsev
Dmitry:

See this function and test if against a large block of text doing a case insensitive replace on a moderate length phrase. Match it in speed against whatever is in the RTL and see if my function is faster and by how much.

function StrReplace(const S, OldPattern, NewPattern: string; IgnoreCase: Boolean = False): string;

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
Oh and I forget, add in a test against a multiple replacement scenario, that is making many replaces in one call to StrReplace.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

dmitry boyarintsev
In reply to this post by Anthony Walter-3
On Tue, Feb 17, 2015 at 10:50 PM, Anthony Walter <[hidden email]> wrote:
But if anyone wants to test my StrFindBuffer and StrFindBufferI to gauge their performance against similar RTL library routines, I believe you'll find they are significantly faster. As a consequence all other dependent functions (IndexOf, Match, Replace, Split, and more) would be significantly faster as well.

Here are copies of the relevant code: http://www.getlazarus.org/helpers/string/
 
 I see, you've implemented Boyer–Moore–Horspool algorithm for the string search. 

Why don't you take part in patch-fest then? http://bugs.freepascal.org/view.php?id=26864


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
Feel free to submit a patch for me, given the code I've posted. That is, after you test and validate the speed gains. 

I am busy finishing up this project (http://www.codebot.org/snapshop/) on Linux and Mac at the moment, and then creating a new video walk through (my prior one http://www.getlazarus.org/videos/reports/). This time I'll have access to some professional voice over work.



_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

dmitry boyarintsev
On Tue, Feb 17, 2015 at 11:24 PM, Anthony Walter <[hidden email]> wrote:
I am busy finishing up this project (http://www.codebot.org/snapshop/) on Linux and Mac at the moment, and then creating a new video walk through (my prior one http://www.getlazarus.org/videos/reports/). This time I'll have access to some professional voice over work.

On the snapshop page - under "Langauges" section the screenshot shows Russian flag for "French" language. 

thanks,
Dmitry

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

silvioprog
In reply to this post by Anthony Walter-3
On Wed, Feb 18, 2015 at 12:50 AM, Anthony Walter <[hidden email]> wrote:
I wasn't aware of XE's string helper, so no. 

But if anyone wants to test my StrFindBuffer and StrFindBufferI to gauge their performance against similar RTL library routines, I believe you'll find they are significantly faster. As a consequence all other dependent functions (IndexOf, Match, Replace, Split, and more) would be significantly faster as well.

Here are copies of the relevant code:


Very nice!

What is the license of it? I'll test it soon.

Any way, thanks for share it! =)

P.S.: IMHO you could send some patch to FPC team check it too.

--
Silvio Clécio
My public projects - github.com/silvioprog

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

silvioprog
In reply to this post by Anthony Walter-3
On Wed, Feb 18, 2015 at 1:24 AM, Anthony Walter <[hidden email]> wrote:
Feel free to submit a patch for me, given the code I've posted. That is, after you test and validate the speed gains.

Dmitry?
 
I am busy finishing up this project (http://www.codebot.org/snapshop/) on Linux and Mac at the moment, and then creating a new video walk through (my prior one http://www.getlazarus.org/videos/reports/). This time I'll have access to some professional voice over work.

Saved in my favorites! =) Congratulations, your site and your projects are very good.

I'm working in custfcgi unit to send a patch to bugtracker, but after that I'll see your project. Please don't forget to send a patch - you are the best guy to do it, because you is the author hehe. =D.

--
Silvio Clécio
My public projects - github.com/silvioprog

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

dmitry boyarintsev


On Wed, Feb 18, 2015 at 12:05 AM, silvioprog <[hidden email]> wrote:
On Wed, Feb 18, 2015 at 1:24 AM, Anthony Walter <[hidden email]> wrote:
Feel free to submit a patch for me, given the code I've posted. That is, after you test and validate the speed gains.

Dmitry?
 
I'm not interested.

thanks,
Dmitry 


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Sven Barth-2
In reply to this post by Anthony Walter-3
On 17.02.2015 23:28, Anthony Walter wrote:

> I tried this out today on FPC fixes_3_0 and was surprised to see it worked:
>
> type
>    StringHelper = record helper for string
>    private
>      function GetLength: Integer;
>    procedure SetLength(Value: Integer);
>      function GetIsEmpty: Boolean;
>      function GetIsWhitespace: Boolean;
>    public
>      function BeginsWith(const S: string): Boolean;
>      function EndsWith(const S: string): Boolean;
>      function Trim: string;
>      property Length: Integer read GetLength write SetLength;
>      property IsEmpty: Boolean read GetIsEmpty;
>      property IsWhitespace: Boolean read GetIsWhitespace;
>    end;
>
> I love this and would like to know if this is going to be an officially
> supported feature and can I depend on it to work going forward?

http://wiki.freepascal.org/FPC_New_Features_Trunk#Support_for_type_helpers

Please note that if you use "String" the types the helper will apply to
will depend on whatever "String" currently is. Maybe it would be better
to explicitely use "AnsiString" and "UnicodeString" to avoid potential
surprises.
And just in case: type helpers might also be used on constants:

=== code begin ===

Writeln('Test'.Length);

=== code end ===

Regards,
Sven

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Record helpers on built in types?

Anthony Walter-3
Sven, thanks for all these improvements you've made. From this page http://wiki.freepascal.org/Helper_types#Syntax can you explain what [hint modifiers] are, and also how does the optional (BaseHelper) come into play?

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
12