Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2016-04

Any chance to add the TStringBuilder to FCL?

25 messages · 10 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

leledumbo
to silvioprog
Is there any chance to add a class like Delphi's TStringBuilder to FCL? It

would be very useful to port Delphi code libraries to Free Pascal.

That exists mainly to overcome the read-only, 0-based string implementation limitations in Delphi NextGen, doesn't it? Porting will still require 0-based string implementation, that class implementation alone won't be enough.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Any-chance-to-add-the-TStringBuilder-to-FCL-tp5724927p5724928.html Sent from the Free Pascal - General mailing list .
Sven Barth
to leledumbo
leledumbo wrote 7 lines
> Is there any chance to add a class like Delphi's TStringBuilder to FCL? It would be very useful to port Delphi code libraries to Free Pascal. That exists mainly to overcome the read-only, 0-based string implementation limitations in Delphi NextGen, doesn't it? Porting will still require 0-based string implementation, that class implementation alone won't be enough.

We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is used (it's a local switch). It works with Ansi-, Wide- and UnicodeString, but not with ShortString.

The following example will print

=== output begin ===
l
o
=== output end ===

=== code begin ===

program tzerostr;
{$H+}
var
  s: String;
begin
  s := 'Hello World';
  Writeln(s[4]);
{$ZeroBasedStrings On}
  Writeln(s[4]);
end.

=== code end ===

Regards,
Sven

Graeme Geldenhuys
to Sven Barth
Sven Barth wrote
We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is used (it's a local switch).

Wow, learnt something new again. Never new that existed. I really should read the “what’s new” document.

Regards,
Graeme

Sven Barth
to Graeme Geldenhuys

Am 14.04.2016 23:22 schrieb "Graeme Geldenhuys" <

Show quoted text 8 lines
: On 2016-04-14 19:27, Sven Barth wrote: > We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is > used (it's a local switch). Wow, learnt something new again. Never new that existed. I really should read the “what’s new” document.

Seems like that wasn't added to the New Features 3.0.0 page anyway :/

Regards,
Sven

Jürgen Hestermann
to Graeme Geldenhuys: Wow, learnt something new again. Never new that existed. I really should read the…
Graeme Geldenhuys wrote
On 2016-04-14 19:27, Sven Barth wrote: > We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is > used (it's a local switch). Wow, learnt something new again. Never new that existed.

Me too.
Though I will not use it.

Is there also a switch
{$OneBasedDynArrays On} ?
I would love it.
No more confusion about first and last element index.

Michael Van Canneyt
to Sven Barth: Am 14.04.2016 23:22 schrieb "Graeme Geldenhuys" < Seems like that wasn't added to the New…
Sven Barth wrote 11 lines
Am 14.04.2016 23:22 schrieb "Graeme Geldenhuys" < >: > > On 2016-04-14 19:27, Sven Barth wrote: >> We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is >> used (it's a local switch). > > Wow, learnt something new again. Never new that existed. I really should > read the “what’s new” document. Seems like that wasn't added to the New Features 3.0.0 page anyway :/

Even I didn't know we supported this. It's definitely not documented either.

Michael.

Graeme Geldenhuys
to Jürgen Hestermann: Me too. Though I will not use it. Is there also a switch {$OneBasedDynArrays On} ? I…
Jürgen Hestermann wrote
Though I will not use it.

Neither would I. I don't see the need for it.

Is there also a switch {$OneBasedDynArrays On} ? No more confusion about first and last element index.

You really should be using low() and high() instead. ;-)

Regards,
Graeme

fpGUI Toolkit - a cross-platform GUI toolkit using Free Pascal http://fpgui.sourceforge.net/ My public PGP key: http://tinyurl.com/graeme-pgp
Sven Barth
to Graeme Geldenhuys

Am 15.04.2016 10:47 schrieb "Graeme Geldenhuys" <

Show quoted text 6 lines
: > Is there also a switch > {$OneBasedDynArrays On} ? > No more confusion about first and last element index. You really should be using low() and high() instead. ;-)

Definitely (and they also work for strings now ;) - or at least low() does).

Regards,
Sven

Jürgen Hestermann
to Graeme Geldenhuys: Neither would I. I don't see the need for it. You really should be using low() and high()…
Graeme Geldenhuys wrote
> Is there also a switch > {$OneBasedDynArrays On} ? > No more confusion about first and last element index. You really should be using low() and high() instead. ;-)

So why do we need {$ZeroBasedStrings On} at all? ;-)

Of course, when you simply want to traverse all elements from the first to the last you can use low() and high(). But I would not use this for strings as

for i := 1 to Length(S)

is IMO more readable than

for i := low(s) to high(S)

(where it's unclear, whether high() means the highest *possible* or the highest *current* index).

And I often need to calculate or store indices.
Then I have to take into account where counting starts and ends which is unintuitive in dynamic arrays (not Pascal like). When I set

INDEX := 2;

then I always have to remind me that this means that it's the 3rd index in dynamic arrays while it's the 2nd one in strings.

Jürgen Hestermann
to Jürgen Hestermann

Another advantage of having 1-based indeces in dyn. arrays would be that you could store indeces in unsigned integers while with 0-based indices high() may give -1.

Sven Barth
to Jürgen Hestermann
"Jürgen Hestermann" wrote
Another advantage of having 1-based indeces in dyn. arrays would be that you could store indeces in unsigned integers while with 0-based indices high() may give -1.

Indices in Pascal are always signed.

Regards,
Sven

leledumbo
to Sven Barth: We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is used (it's a…
We already have zero based strings in 3.0.0 if {$ZeroBasedStrings On} is used (it's a local switch). It works with Ansi-, Wide- and UnicodeString, but not with ShortString.

*shocked* so many hidden treasures in FPC...

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Any-chance-to-add-the-TStringBuilder-to-FCL-tp5724927p5724969.html Sent from the Free Pascal - General mailing list .
Jürgen Hestermann
to Sven Barth: Indices in Pascal are always signed. Sven
Sven Barth wrote 10 lines
Am 15.04.2016 18:37 schrieb "Jürgen Hestermann" < >: > > Another advantage of having 1-based indeces in dyn. arrays > would be that you could store indeces in unsigned integers > while with 0-based indices high() may give -1. Indices in Pascal are always signed.

Yes, but I could store indices in DWORD if they would be 1-based and would not risk an exception if the index is "not valid" (which would be 0 in this case while it's -1 for 0-based indices). I would not be forced to make sure it is an signed integer where I store it.

Marco van de Voort
to Jürgen Hestermann

In our previous episode, J?rgen Hestermann said:

Show quoted text 8 lines
> > while with 0-based indices high() may give -1. > > Indices in Pascal are always signed. > > Yes, but I could store indices in DWORD if they would be 1-based and would not risk an exception if the index is "not valid" (which would be 0 in this case while it's -1 for 0-based indices).

You would have to check everywhere before decrementing. This can be annoying in loops. (it is that way in M2 btw, where the basetype is unsigned. Not happy with that)

Dmitry Boyarintsev
to Jürgen Hestermann: I don't know what you mean. A For-loop has it's limits anyway. And when decrementing…

On Sat, Apr 16, 2016 at 2:28 PM, Jürgen Hestermann <

Show quoted text 9 lines
wrote: I don't know what you mean. A For-loop has it's limits anyway. And when decrementing 'manually' I would stop if INDEX=0. For 0-based arrays I would stop if INDEX=-1? What would be different? For 1-based arrays I would never get an index<0 because it problem is with using "unsigned" as an index (rather than zero- vs one-

based arrays)
Take a while loop as an example, where index can change multiple times.

Current solution:
while i>=0 do
  if cond then dec(i);
  dec(i);
end;
Unsigned index solution
while i>=0 do
  if cond then if i>0 then dec(i);
  if i>0 then dec(i);
end;

Without these checks, unsigned integer would loop over to $FFFFFFFF and will continue.

thanks,
Dmitry

Jürgen Hestermann
to Marco van de Voort: In our previous episode, J?rgen Hestermann said: You would have to check everywhere…
Marco van de Voort wrote 6 lines
> Yes, but I could store indices in DWORD if they would be 1-based > and would not risk an exception if the index is "not valid" (which > would be 0 in this case while it's -1 for 0-based indices). You would have to check everywhere before decrementing. This can be annoying in loops. (it is that way in M2 btw, where the basetype is unsigned. Not happy with that)

I don't know what you mean.
A For-loop has it's limits anyway.
And when decrementing 'manually' I would stop if INDEX=0. For 0-based arrays I would stop if INDEX=-1?
What would be different?
For 1-based arrays I would never get an index<0
because it stops at zero.

Jürgen Hestermann
to Dmitry Boyarintsev: On Sat, Apr 16, 2016 at 2:28 PM, Jürgen Hestermann < based arrays) Take a while loop as…
Dmitry Boyarintsev wrote 13 lines
The problem is with using "unsigned" as an index (rather than zero- vs one- based arrays) Take a while loop as an example, where index can change multiple times. Current solution: while i>=0 do if cond then dec(i); dec(i); end; Unsigned index solution while i>=0 do if cond then if i>0 then dec(i); if i>0 then dec(i); end; Without these checks, unsigned integer would loop over to $FFFFFFFF and will continue.

That looks to my like an very artifical example.
I never came over a loop where I (conditionally)
decremented the index twice.
But of course, if you have such a case, then you
can only use signed intergers.

But in all the following cases I could used an unsigned integer (when having 1-based arrays):

1.) for i := low(array) to high(array)

2.) repeat or while loops where the index is in- or decremented by a maximum of 1 (which IMO is the case in 99,9% of all such loops).

3.) When storing an array index into a variable for later use.

Nevertheless, using unsigned integers was only one aspect of 1-based arrays. The main one for me was, that it is much more intuitive and therefore less error prone. I already often had errors when calculating indices for 0-based arrays.

And why was a directive implemented to use 0-based indices even for strings but none for 1-based indices in dynamic arrays? IMO the latter would be much more desired.

Marco van de Voort
to Jürgen Hestermann: I don't know what you mean. A For-loop has it's limits anyway. And when decrementing…

In our previous episode, J?rgen Hestermann said:

Show quoted text 5 lines
> in loops. (it is that way in M2 btw, where the basetype is unsigned. Not > happy with that) I don't know what you mean. A For-loop has it's limits anyway.

Limits like in

for i:=0 to someexpression.count-1

are evaluated as expression before using the result to for. If count=0 this would become for i:=0 to $FFFFFFFF, so you need to guard this with a if count>0 then.

This is a common construct so quite annoying.

Sven Barth
to Jürgen Hestermann: That looks to my like an very artifical example. I never came over a loop where I…
"Jürgen Hestermann" wrote
And why was a directive implemented to use 0-based indices even for strings but none for 1-based indices in dynamic arrays? IMO the latter would be much more desired.

The usual reason: Delphi compatibility. If Delphi wouldn't have that directive, we wouldn't have that either, because most others are content with the indices as they are.

Regards,
Sven

Luca Olivetti
to Marco van de Voort: In our previous episode, J?rgen Hestermann said: Limits like in for i:=0 to…

El 18/04/16 a les 09:53, Marco van de Voort ha escrit:

Show quoted text 14 lines
In our previous episode, J?rgen Hestermann said: > > in loops. (it is that way in M2 btw, where the basetype is unsigned. Not > > happy with that) > > I don't know what you mean. > A For-loop has it's limits anyway. Limits like in for i:=0 to someexpression.count-1 are evaluated as expression before using the result to for. If count=0 this would become for i:=0 to $FFFFFFFF, so you need to guard this with a if count>0 then.

Wait, doesn't that evaluate to

  for i:=0 to -1

at least if count is a signed integer?

Bye

Luca
Jürgen Hestermann
to Marco van de Voort: In our previous episode, J?rgen Hestermann said: Limits like in for i:=0 to…
Marco van de Voort wrote 8 lines
Limits like in for i:=0 to someexpression.count-1 are evaluated as expression before using the result to for. If count=0 this would become for i:=0 to $FFFFFFFF, so you need to guard this with a if count>0 then.

Well, for 1-based arrays it would be

for i := 1 to someexpression.count

(without the annyoing -1).
In general I can make sure that somexpression.count is zero or larger when I use it to determine an index for my array.
The same would be

for i := low(array) to high(array)

which is very common and where I would not need to use an unsigned integer.

Jürgen Hestermann
to Sven Barth: The usual reason: Delphi compatibility. If Delphi wouldn't have that directive, we…
Sven Barth wrote 9 lines
Am 18.04.2016 07:58 schrieb "Jürgen Hestermann" < >: > And why was a directive implemented to use 0-based indices > even for strings but none for 1-based indices in dynamic arrays? > IMO the latter would be much more desired. The usual reason: Delphi compatibility. If Delphi wouldn't have that directive, we wouldn't have that either, because most others are content with the indices as they are.

Seems that whenever something goes into the wrong
direction then always Delphi is the culprit. ;-(